Subversion Repositories Kolibri OS

Rev

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

Rev 9890 Rev 10007
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2013-2022. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2013-2022. All rights reserved. ;;
4
;;  Distributed under terms of the GNU General Public License   ;;
4
;;  Distributed under terms of the GNU General Public License   ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
7
 
8
$Revision: 9890 $
8
$Revision: 10007 $
9
 
9
 
10
 
10
 
11
include 'xfs.inc'
11
include 'xfs.inc'
12
 
12
 
13
macro omit_frame_pointer_prologue procname,flag,parmbytes,localbytes,reglist {
13
macro omit_frame_pointer_prologue procname,flag,parmbytes,localbytes,reglist {
14
  local loc
14
  local loc
15
  loc = (localbytes+3) and (not 3)
15
  loc = (localbytes+3) and (not 3)
16
  if localbytes
16
  if localbytes
17
        sub     esp, loc
17
        sub     esp, loc
18
  end if
18
  end if
19
  irps reg, reglist \{ push reg \}
19
  irps reg, reglist \{ push reg \}
20
  counter = 0
20
  counter = 0
21
  irps reg, reglist \{counter = counter+1 \}
21
  irps reg, reglist \{counter = counter+1 \}
22
  parmbase@proc equ esp+counter*4+loc+4
22
  parmbase@proc equ esp+counter*4+loc+4
23
  localbase@proc equ esp
23
  localbase@proc equ esp
24
}
24
}
25
 
25
 
26
macro omit_frame_pointer_epilogue procname,flag,parmbytes,localbytes,reglist {
26
macro omit_frame_pointer_epilogue procname,flag,parmbytes,localbytes,reglist {
27
  local loc
27
  local loc
28
  loc = (localbytes+3) and (not 3)
28
  loc = (localbytes+3) and (not 3)
29
  irps reg, reglist \{ reverse pop reg \}
29
  irps reg, reglist \{ reverse pop reg \}
30
  if localbytes
30
  if localbytes
31
        lea     esp, [esp+loc]
31
        lea     esp, [esp+loc]
32
  end if
32
  end if
33
  if flag and 10000b
33
  if flag and 10000b
34
        retn
34
        retn
35
  else
35
  else
36
        retn    parmbytes
36
        retn    parmbytes
37
  end if
37
  end if
38
}
38
}
39
 
39
 
40
prologue@proc equ omit_frame_pointer_prologue
40
prologue@proc equ omit_frame_pointer_prologue
41
epilogue@proc equ omit_frame_pointer_epilogue
41
epilogue@proc equ omit_frame_pointer_epilogue
42
 
42
 
43
macro movbe reg, arg {
43
macro movbe reg, arg {
44
 if CPUID_MOVBE eq Y
44
 if CPUID_MOVBE eq Y
45
        movbe   reg, arg
45
        movbe   reg, arg
46
 else
46
 else
47
        mov     reg, arg
47
        mov     reg, arg
48
  if reg in 
48
  if reg in 
49
        bswap   reg
49
        bswap   reg
50
  else if ax eq reg
50
  else if ax eq reg
51
        xchg    al, ah
51
        xchg    al, ah
52
  else if bx eq reg
52
  else if bx eq reg
53
        xchg    bl, bh
53
        xchg    bl, bh
54
  else if cx eq reg
54
  else if cx eq reg
55
        xchg    cl, ch
55
        xchg    cl, ch
56
  else if dx eq reg
56
  else if dx eq reg
57
        xchg    dl, dh
57
        xchg    dl, dh
58
  else
58
  else
59
   err
59
   err
60
  end if
60
  end if
61
 end if
61
 end if
62
}
62
}
63
 
63
 
64
;
64
;
65
; This file contains XFS related code.
65
; This file contains XFS related code.
66
; For more information on XFS check links and source below.
66
; For more information on XFS check links and source below.
67
;
67
;
68
; 1. https://xfs.wiki.kernel.org/
68
; 1. https://xfs.wiki.kernel.org/
69
;
69
;
70
; 2. XFS Algorithms & Data Structures:
70
; 2. XFS Algorithms & Data Structures:
71
;    git://git.kernel.org/pub/scm/fs/xfs/xfs-documentation.git
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
72
;    https://mirrors.edge.kernel.org/pub/linux/utils/fs/xfs/docs/xfs_filesystem_structure.pdf
73
;
73
;
74
; 3. Linux source at https://www.kernel.org/
74
; 3. Linux source at https://www.kernel.org/
75
;    git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
75
;    git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
76
;    /fs/xfs
76
;    /fs/xfs
77
;
77
;
78
 
78
 
79
iglobal
79
iglobal
80
align 4
80
align 4
81
xfs._.user_functions:
81
xfs._.user_functions:
82
        dd      xfs._.free
82
        dd      xfs._.free
83
        dd      (xfs._.user_functions_end-xfs._.user_functions-4)/4
83
        dd      (xfs._.user_functions_end-xfs._.user_functions-4)/4
84
        dd      xfs_Read
84
        dd      xfs_Read
85
        dd      xfs_ReadFolder
85
        dd      xfs_ReadFolder
86
        dd      0;xfs_Rewrite
86
        dd      0;xfs_Rewrite
87
        dd      0;xfs_Write
87
        dd      0;xfs_Write
88
        dd      0;xfs_SetFileEnd
88
        dd      0;xfs_SetFileEnd
89
        dd      xfs_GetFileInfo
89
        dd      xfs_GetFileInfo
90
xfs._.user_functions_end:
90
xfs._.user_functions_end:
91
endg
91
endg
92
 
92
 
93
; test partition type (valid XFS one?)
93
; test partition type (valid XFS one?)
94
; alloc and fill XFS (see xfs.inc) structure
94
; alloc and fill XFS (see xfs.inc) structure
95
; this function is called for each partition
95
; this function is called for each partition
96
; return 0 (not XFS or invalid) / pointer to partition structure
96
; return 0 (not XFS or invalid) / pointer to partition structure
97
proc xfs_create_partition uses ebx esi edi
97
proc xfs_create_partition uses ebx esi edi
98
        ; check XFS signature
98
        ; check XFS signature
99
        cmp     [ebx+xfs_sb.sb_magicnum], XFS_SB_MAGIC
99
        cmp     [ebx+xfs_sb.sb_magicnum], XFS_SB_MAGIC
100
        jnz     .error_nofree
100
        jnz     .error_nofree
101
        ; test for supported feature flags and version in sb_versionnum
101
        ; test for supported feature flags and version in sb_versionnum
102
        movzx   eax, [ebx+xfs_sb.sb_versionnum]
102
        movzx   eax, [ebx+xfs_sb.sb_versionnum]
103
        xchg    al, ah
103
        xchg    al, ah
104
        ; allow only known and supported features
104
        ; allow only known and supported features
105
        ; return error otherwise
105
        ; return error otherwise
106
        test    eax, NOT XFS_SB_VERSION_SUPPORTED
106
        test    eax, NOT XFS_SB_VERSION_SUPPORTED
107
        jnz     .error_nofree
107
        jnz     .error_nofree
108
        ; version < 4 obsolete, not supported
108
        ; version < 4 obsolete, not supported
109
        ; version = 4,5 supported
109
        ; version = 4,5 supported
110
        ; version > 5 unknown
110
        ; version > 5 unknown
111
        and     al, XFS_SB_VERSION_NUMBITS
111
        and     al, XFS_SB_VERSION_NUMBITS
112
        cmp     al, 4
112
        cmp     al, 4
113
        jb      .error_nofree
113
        jb      .error_nofree
114
        cmp     al, 5
114
        cmp     al, 5
115
        ja      .error_nofree
115
        ja      .error_nofree
116
        ; if MOREBITS bit is set, additional feature flags are in sb_features2
116
        ; if MOREBITS bit is set, additional feature flags are in sb_features2
117
        test    eax, XFS_SB_VERSION_MOREBITSBIT
117
        test    eax, XFS_SB_VERSION_MOREBITSBIT
118
        jz      @f
118
        jz      @f
119
        movbe   eax, [ebx+xfs_sb.sb_features2]
119
        movbe   eax, [ebx+xfs_sb.sb_features2]
120
        test    eax, NOT XFS_SB_VERSION2_SUPPORTED
120
        test    eax, NOT XFS_SB_VERSION2_SUPPORTED
121
        jnz     .error_nofree
121
        jnz     .error_nofree
122
@@:
122
@@:
123
        movbe   eax, [ebx+xfs_sb.sb_features_incompat]
123
        movbe   eax, [ebx+xfs_sb.sb_features_incompat]
124
        test    eax, NOT XFS_SB_FEAT_INCOMPAT_SUPPORTED
124
        test    eax, NOT XFS_SB_FEAT_INCOMPAT_SUPPORTED
125
        jnz     .error_nofree
125
        jnz     .error_nofree
126
        ; all presented features are either supported or don't affect reading
126
        ; all presented features are either supported or don't affect reading
127
        movi    eax, sizeof.XFS
127
        movi    eax, sizeof.XFS
128
        call    malloc
128
        call    malloc
129
        mov     edi, eax
129
        mov     edi, eax
130
        test    eax, eax
130
        test    eax, eax
131
        jz      .error
131
        jz      .error
132
 
132
 
133
        ; standard partition initialization, common for all file systems
133
        ; standard partition initialization, common for all file systems
134
        mov     eax, dword[ebp+PARTITION.FirstSector+DQ.lo]
134
        mov     eax, dword[ebp+PARTITION.FirstSector+DQ.lo]
135
        mov     dword[edi+XFS.FirstSector+DQ.lo], eax
135
        mov     dword[edi+XFS.FirstSector+DQ.lo], eax
136
        mov     eax, dword[ebp+PARTITION.FirstSector+DQ.hi]
136
        mov     eax, dword[ebp+PARTITION.FirstSector+DQ.hi]
137
        mov     dword[edi+XFS.FirstSector+DQ.hi], eax
137
        mov     dword[edi+XFS.FirstSector+DQ.hi], eax
138
        mov     eax, dword[ebp+PARTITION.Length+DQ.lo]
138
        mov     eax, dword[ebp+PARTITION.Length+DQ.lo]
139
        mov     dword[edi+XFS.Length+DQ.lo], eax
139
        mov     dword[edi+XFS.Length+DQ.lo], eax
140
        mov     eax, dword[ebp+PARTITION.Length+DQ.hi]
140
        mov     eax, dword[ebp+PARTITION.Length+DQ.hi]
141
        mov     dword[edi+XFS.Length+DQ.hi], eax
141
        mov     dword[edi+XFS.Length+DQ.hi], eax
142
        mov     eax, [ebp+PARTITION.Disk]
142
        mov     eax, [ebp+PARTITION.Disk]
143
        mov     [edi+XFS.Disk], eax
143
        mov     [edi+XFS.Disk], eax
144
        mov     [edi+XFS.FSUserFunctions], xfs._.user_functions
144
        mov     [edi+XFS.FSUserFunctions], xfs._.user_functions
145
        ; here we initialize only one mutex (for the entire partition)
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
146
        ; XFS potentially allows parallel r/w access to different AGs, keep it in mind
147
        lea     ecx, [edi+XFS.Lock]
147
        lea     ecx, [edi+XFS.Lock]
148
        call    mutex_init
148
        call    mutex_init
149
 
149
 
150
;        movzx   eax, [ebx+xfs_sb.sb_sectsize]
150
;        movzx   eax, [ebx+xfs_sb.sb_sectsize]
151
;        xchg    al, ah
151
;        xchg    al, ah
152
        mov     eax, [eax+DISK.MediaInfo.SectorSize]
152
        mov     eax, [eax+DISK.MediaInfo.SectorSize]
153
        mov     [edi+XFS.sectsize], eax
153
        mov     [edi+XFS.sectsize], eax
154
 
154
 
155
        movbe   eax, [ebx+xfs_sb.sb_blocksize]
155
        movbe   eax, [ebx+xfs_sb.sb_blocksize]
156
        mov     [edi+XFS.blocksize], eax
156
        mov     [edi+XFS.blocksize], eax
157
 
157
 
158
        movzx   eax, [ebx+xfs_sb.sb_versionnum]
158
        movzx   eax, [ebx+xfs_sb.sb_versionnum]
159
        xchg    al, ah
159
        xchg    al, ah
160
        mov     [edi+XFS.versionnum], eax
160
        mov     [edi+XFS.versionnum], eax
161
        and     eax, XFS_SB_VERSION_NUMBITS
161
        and     eax, XFS_SB_VERSION_NUMBITS
162
        mov     [edi+XFS.version], eax
162
        mov     [edi+XFS.version], eax
163
 
163
 
164
        mov     [edi+XFS.conv_time_to_kos_epoch], xfs._.conv_time_to_kos_epoch
164
        mov     [edi+XFS.conv_time_to_kos_epoch], xfs._.conv_time_to_kos_epoch
165
        mov     [edi+XFS.nextents_offset], xfs_inode.di_core.di_nextents
165
        mov     [edi+XFS.nextents_offset], xfs_inode.di_core.di_nextents
166
 
166
 
167
        movbe   eax, [ebx+xfs_sb.sb_features2]
167
        movbe   eax, [ebx+xfs_sb.sb_features2]
168
        mov     [edi+XFS.features2], eax
168
        mov     [edi+XFS.features2], eax
169
        cmp     [edi+XFS.version], 5
169
        cmp     [edi+XFS.version], 5
170
        jz      .v5
170
        jz      .v5
171
.v4:
171
.v4:
172
        mov     [edi+XFS.inode_core_size], sizeof.xfs_dinode_core
172
        mov     [edi+XFS.inode_core_size], sizeof.xfs_dinode_core
173
        test    eax, XFS_SB_VERSION2_FTYPE
173
        test    eax, XFS_SB_VERSION2_FTYPE
174
        setnz   al
174
        setnz   al
175
        movzx   eax, al
175
        movzx   eax, al
176
        mov     [edi+XFS.ftype_size], eax
176
        mov     [edi+XFS.ftype_size], eax
177
        mov     [edi+XFS.dir_block_magic], XFS_DIR2_BLOCK_MAGIC
177
        mov     [edi+XFS.dir_block_magic], XFS_DIR2_BLOCK_MAGIC
178
        mov     [edi+XFS.dir_data_magic], XFS_DIR2_DATA_MAGIC
178
        mov     [edi+XFS.dir_data_magic], XFS_DIR2_DATA_MAGIC
179
        mov     [edi+XFS.dir_leaf1_magic], XFS_DIR2_LEAF1_MAGIC
179
        mov     [edi+XFS.dir_leaf1_magic], XFS_DIR2_LEAF1_MAGIC
180
        mov     [edi+XFS.dir_leafn_magic], XFS_DIR2_LEAFN_MAGIC
180
        mov     [edi+XFS.dir_leafn_magic], XFS_DIR2_LEAFN_MAGIC
181
        mov     [edi+XFS.da_node_magic], XFS_DA_NODE_MAGIC
181
        mov     [edi+XFS.da_node_magic], XFS_DA_NODE_MAGIC
182
        mov     [edi+XFS.bmap_magic], XFS_BMAP_MAGIC
182
        mov     [edi+XFS.bmap_magic], XFS_BMAP_MAGIC
-
 
183
        mov     [edi+XFS.dirx_leaf_ents_offset], xfs_dir2_leaf.ents
-
 
184
        mov     [edi+XFS.dirx_leaf_hdr_count_offset], xfs_dir2_leaf_hdr.count
183
        mov     [edi+XFS.dir_block_size], sizeof.xfs_dir2_data_hdr
185
        mov     [edi+XFS.dir_block_size], sizeof.xfs_dir2_data_hdr
184
        mov     [edi+XFS.bmbt_block_size], sizeof.xfs_bmbt_block
186
        mov     [edi+XFS.bmbt_block_size], sizeof.xfs_bmbt_block
185
        mov     [edi+XFS.da_blkinfo_size], sizeof.xfs_da_blkinfo
187
        mov     [edi+XFS.da_blkinfo_size], sizeof.xfs_da_blkinfo
186
        jmp     .vcommon
188
        jmp     .vcommon
187
.v5:
189
.v5:
188
        mov     [edi+XFS.inode_core_size], sizeof.xfs_dinode3_core
190
        mov     [edi+XFS.inode_core_size], sizeof.xfs_dinode3_core
189
        movbe   eax, [ebx+xfs_sb.sb_features_incompat]
191
        movbe   eax, [ebx+xfs_sb.sb_features_incompat]
190
        mov     [edi+XFS.features_incompat], eax
192
        mov     [edi+XFS.features_incompat], eax
191
        test    eax, XFS_SB_FEAT_INCOMPAT_FTYPE
193
        test    eax, XFS_SB_FEAT_INCOMPAT_FTYPE
192
        setnz   al
194
        setnz   al
193
        movzx   eax, al
195
        movzx   eax, al
194
        mov     [edi+XFS.ftype_size], eax
196
        mov     [edi+XFS.ftype_size], eax
195
        mov     [edi+XFS.dir_block_magic], XFS_DIR3_BLOCK_MAGIC
197
        mov     [edi+XFS.dir_block_magic], XFS_DIR3_BLOCK_MAGIC
196
        mov     [edi+XFS.dir_data_magic], XFS_DIR3_DATA_MAGIC
198
        mov     [edi+XFS.dir_data_magic], XFS_DIR3_DATA_MAGIC
197
        mov     [edi+XFS.dir_leaf1_magic], XFS_DIR3_LEAF1_MAGIC
199
        mov     [edi+XFS.dir_leaf1_magic], XFS_DIR3_LEAF1_MAGIC
198
        mov     [edi+XFS.dir_leafn_magic], XFS_DIR3_LEAFN_MAGIC
200
        mov     [edi+XFS.dir_leafn_magic], XFS_DIR3_LEAFN_MAGIC
199
        mov     [edi+XFS.da_node_magic], XFS_DA3_NODE_MAGIC
201
        mov     [edi+XFS.da_node_magic], XFS_DA3_NODE_MAGIC
200
        mov     [edi+XFS.bmap_magic], XFS_BMAP3_MAGIC
202
        mov     [edi+XFS.bmap_magic], XFS_BMAP3_MAGIC
-
 
203
        mov     [edi+XFS.dirx_leaf_ents_offset], xfs_dir3_leaf.ents
-
 
204
        mov     [edi+XFS.dirx_leaf_hdr_count_offset], xfs_dir3_leaf_hdr.count
201
        mov     [edi+XFS.dir_block_size], sizeof.xfs_dir3_data_hdr
205
        mov     [edi+XFS.dir_block_size], sizeof.xfs_dir3_data_hdr
202
        mov     [edi+XFS.bmbt_block_size], sizeof.xfs_bmbt3_block
206
        mov     [edi+XFS.bmbt_block_size], sizeof.xfs_bmbt3_block
203
        mov     [edi+XFS.da_blkinfo_size], sizeof.xfs_da3_blkinfo
207
        mov     [edi+XFS.da_blkinfo_size], sizeof.xfs_da3_blkinfo
204
        test    [edi+XFS.features_incompat], XFS_SB_FEAT_INCOMPAT_BIGTIME
208
        test    [edi+XFS.features_incompat], XFS_SB_FEAT_INCOMPAT_BIGTIME
205
        jz      @f      ; no bigtime
209
        jz      @f      ; no bigtime
206
        mov     [edi+XFS.conv_time_to_kos_epoch], xfs._.conv_bigtime_to_kos_epoch
210
        mov     [edi+XFS.conv_time_to_kos_epoch], xfs._.conv_bigtime_to_kos_epoch
207
@@:
211
@@:
208
        test    [edi+XFS.features_incompat], XFS_SB_FEAT_INCOMPAT_NREXT64
212
        test    [edi+XFS.features_incompat], XFS_SB_FEAT_INCOMPAT_NREXT64
209
        jz      @f      ; no bigtime
213
        jz      @f      ; no bigtime
210
        mov     [edi+XFS.nextents_offset], xfs_inode.di_core.di_big_nextents.lo_be
214
        mov     [edi+XFS.nextents_offset], xfs_inode.di_core.di_big_nextents.lo_be
211
@@:
215
@@:
212
.vcommon:
216
.vcommon:
213
 
217
 
214
        movzx   eax, [ebx+xfs_sb.sb_inodesize]
218
        movzx   eax, [ebx+xfs_sb.sb_inodesize]
215
        xchg    al, ah
219
        xchg    al, ah
216
        mov     [edi+XFS.inodesize], eax
220
        mov     [edi+XFS.inodesize], eax
217
 
221
 
218
        movzx   eax, [ebx+xfs_sb.sb_inopblock]
222
        movzx   eax, [ebx+xfs_sb.sb_inopblock]
219
        xchg    al, ah
223
        xchg    al, ah
220
        mov     [edi+XFS.inopblock], eax
224
        mov     [edi+XFS.inopblock], eax
221
 
225
 
222
        movzx   eax, [ebx+xfs_sb.sb_blocklog]
226
        movzx   eax, [ebx+xfs_sb.sb_blocklog]
223
        mov     [edi+XFS.blocklog], eax
227
        mov     [edi+XFS.blocklog], eax
224
 
228
 
225
;        movzx   eax, [ebx+xfs_sb.sb_sectlog]
229
;        movzx   eax, [ebx+xfs_sb.sb_sectlog]
226
        mov     eax, [edi+XFS.sectsize]
230
        mov     eax, [edi+XFS.sectsize]
227
        bsf     eax, eax
231
        bsf     eax, eax
228
        mov     [edi+XFS.sectlog], eax
232
        mov     [edi+XFS.sectlog], eax
229
 
233
 
230
        movzx   eax, [ebx+xfs_sb.sb_inodelog]
234
        movzx   eax, [ebx+xfs_sb.sb_inodelog]
231
        mov     [edi+XFS.inodelog], eax
235
        mov     [edi+XFS.inodelog], eax
232
 
236
 
233
        movzx   eax, [ebx+xfs_sb.sb_inopblog]
237
        movzx   eax, [ebx+xfs_sb.sb_inopblog]
234
        mov     [edi+XFS.inopblog], eax
238
        mov     [edi+XFS.inopblog], eax
235
 
239
 
236
        movzx   ecx, [ebx+xfs_sb.sb_dirblklog]
240
        movzx   ecx, [ebx+xfs_sb.sb_dirblklog]
237
        mov     [edi+XFS.dirblklog], ecx
241
        mov     [edi+XFS.dirblklog], ecx
238
        movi    eax, 1
242
        movi    eax, 1
239
        shl     eax, cl
243
        shl     eax, cl
240
        mov     [edi+XFS.blkpdirblk], eax
244
        mov     [edi+XFS.blkpdirblk], eax
241
 
245
 
242
        movbe   eax, [ebx+xfs_sb.sb_rootino.hi]
246
        movbe   eax, [ebx+xfs_sb.sb_rootino.hi]
243
        mov     [edi+XFS.rootino.lo], eax
247
        mov     [edi+XFS.rootino.lo], eax
244
        movbe   eax, [ebx+xfs_sb.sb_rootino.lo]
248
        movbe   eax, [ebx+xfs_sb.sb_rootino.lo]
245
        mov     [edi+XFS.rootino.hi], eax
249
        mov     [edi+XFS.rootino.hi], eax
246
 
250
 
247
        mov     eax, [edi+XFS.blocksize]
251
        mov     eax, [edi+XFS.blocksize]
248
        mov     ecx, [edi+XFS.dirblklog]
252
        mov     ecx, [edi+XFS.dirblklog]
249
        shl     eax, cl
253
        shl     eax, cl
250
        mov     [edi+XFS.dirblocksize], eax           ; blocks are for files, dirblocks are for directories
254
        mov     [edi+XFS.dirblocksize], eax           ; blocks are for files, dirblocks are for directories
251
 
255
 
252
        ; sector is always smaller than block
256
        ; sector is always smaller than block
253
        ; so precalculate shift order to allow faster sector_num->block_num conversion
257
        ; so precalculate shift order to allow faster sector_num->block_num conversion
254
        mov     ecx, [edi+XFS.blocklog]
258
        mov     ecx, [edi+XFS.blocklog]
255
        sub     ecx, [edi+XFS.sectlog]
259
        sub     ecx, [edi+XFS.sectlog]
256
        mov     [edi+XFS.sectpblog], ecx
260
        mov     [edi+XFS.sectpblog], ecx
257
 
261
 
258
        mov     eax, 1
262
        mov     eax, 1
259
        shl     eax, cl
263
        shl     eax, cl
260
        mov     [edi+XFS.sectpblock], eax
264
        mov     [edi+XFS.sectpblock], eax
261
 
265
 
262
        movbe   eax, [ebx+xfs_sb.sb_agblocks]
266
        movbe   eax, [ebx+xfs_sb.sb_agblocks]
263
        mov     [edi+XFS.agblocks], eax
267
        mov     [edi+XFS.agblocks], eax
264
 
268
 
265
        movzx   ecx, [ebx+xfs_sb.sb_agblklog]
269
        movzx   ecx, [ebx+xfs_sb.sb_agblklog]
266
        mov     [edi+XFS.agblklog], ecx
270
        mov     [edi+XFS.agblklog], ecx
267
 
271
 
268
        ; get the mask for block numbers
272
        ; get the mask for block numbers
269
        ; block numbers are AG relative!
273
        ; block numbers are AG relative!
270
        ; bitfield length may vary between partitions
274
        ; bitfield length may vary between partitions
271
        mov     eax, 1
275
        mov     eax, 1
272
        xor     edx, edx
276
        xor     edx, edx
273
        shld    edx, eax, cl
277
        shld    edx, eax, cl
274
        shl     eax, cl
278
        shl     eax, cl
275
        sub     eax, 1
279
        sub     eax, 1
276
        sbb     edx, 0
280
        sbb     edx, 0
277
        mov     [edi+XFS.agblockmask.lo], eax
281
        mov     [edi+XFS.agblockmask.lo], eax
278
        mov     [edi+XFS.agblockmask.hi], edx
282
        mov     [edi+XFS.agblockmask.hi], edx
279
 
283
 
280
        ; calculate magic offsets for directories
284
        ; calculate magic offsets for directories
281
        mov     ecx, [edi+XFS.blocklog]
285
        mov     ecx, [edi+XFS.blocklog]
282
        mov     eax, XFS_DIR2_LEAF_OFFSET AND 0xffffffff        ; lo
286
        mov     eax, XFS_DIR2_LEAF_OFFSET AND 0xffffffff        ; lo
283
        mov     edx, XFS_DIR2_LEAF_OFFSET SHR 32                ; hi
287
        mov     edx, XFS_DIR2_LEAF_OFFSET SHR 32                ; hi
284
        shrd    eax, edx, cl
288
        shrd    eax, edx, cl
285
        shr     edx, cl
289
        shr     edx, cl
286
        mov     [edi+XFS.dir2_leaf_offset_blocks.lo], eax
290
        mov     [edi+XFS.dir2_leaf_offset_blocks.lo], eax
287
        mov     [edi+XFS.dir2_leaf_offset_blocks.hi], edx
291
        mov     [edi+XFS.dir2_leaf_offset_blocks.hi], edx
288
 
292
 
289
        mov     ecx, [edi+XFS.blocklog]
293
        mov     ecx, [edi+XFS.blocklog]
290
        mov     eax, XFS_DIR2_FREE_OFFSET AND 0xffffffff        ; lo
294
        mov     eax, XFS_DIR2_FREE_OFFSET AND 0xffffffff        ; lo
291
        mov     edx, XFS_DIR2_FREE_OFFSET SHR 32                ; hi
295
        mov     edx, XFS_DIR2_FREE_OFFSET SHR 32                ; hi
292
        shrd    eax, edx, cl
296
        shrd    eax, edx, cl
293
        shr     edx, cl
297
        shr     edx, cl
294
        mov     [edi+XFS.dir2_free_offset_blocks.lo], eax
298
        mov     [edi+XFS.dir2_free_offset_blocks.lo], eax
295
        mov     [edi+XFS.dir2_free_offset_blocks.hi], edx
299
        mov     [edi+XFS.dir2_free_offset_blocks.hi], edx
296
 
300
 
297
 
301
 
298
        ; allocate memory for temp block, dirblock, inode, etc
302
        ; allocate memory for temp block, dirblock, inode, etc
299
        mov     eax, [edi+XFS.blocksize]
303
        mov     eax, [edi+XFS.blocksize]
300
        call    malloc
304
        call    malloc
301
        mov     [edi+XFS.cur_block], eax
305
        mov     [edi+XFS.cur_block], eax
302
        test    eax, eax
306
        test    eax, eax
303
        jz      .error
307
        jz      .error
304
 
308
 
305
        mov     eax, [edi+XFS.blocksize]
309
        mov     eax, [edi+XFS.blocksize]
306
        call    malloc
310
        call    malloc
307
        mov     [edi+XFS.cur_block_data], eax
311
        mov     [edi+XFS.cur_block_data], eax
308
        test    eax, eax
312
        test    eax, eax
309
        jz      .error
313
        jz      .error
310
 
314
 
311
        ; we do need XFS.blocksize bytes for single inode
315
        ; we do need XFS.blocksize bytes for single inode
312
        ; minimal file system structure is block, inodes are packed in blocks
316
        ; minimal file system structure is block, inodes are packed in blocks
313
        mov     eax, [edi+XFS.blocksize]
317
        mov     eax, [edi+XFS.blocksize]
314
        call    malloc
318
        call    malloc
315
        mov     [edi+XFS.cur_inode], eax
319
        mov     [edi+XFS.cur_inode], eax
316
        test    eax, eax
320
        test    eax, eax
317
        jz      .error
321
        jz      .error
318
 
322
 
319
        mov     eax, [edi+XFS.blocksize]
323
        mov     eax, [edi+XFS.blocksize]
320
        call    malloc
324
        call    malloc
321
        test    eax, eax
325
        test    eax, eax
322
        jz      .error
326
        jz      .error
323
        mov     [edi+XFS.tmp_inode], eax
327
        mov     [edi+XFS.tmp_inode], eax
324
 
328
 
325
        ; current sector
329
        ; current sector
326
        ; only for sector sized structures like AGF
330
        ; only for sector sized structures like AGF
327
        ; inodes usually fit this size, but not always!
331
        ; inodes usually fit this size, but not always!
328
        ; therefore never store inode here
332
        ; therefore never store inode here
329
        mov     eax, [edi+XFS.sectsize]
333
        mov     eax, [edi+XFS.sectsize]
330
        call    malloc
334
        call    malloc
331
        mov     [edi+XFS.cur_sect], eax
335
        mov     [edi+XFS.cur_sect], eax
332
        test    eax, eax
336
        test    eax, eax
333
        jz      .error
337
        jz      .error
334
 
338
 
335
        mov     eax, [edi+XFS.dirblocksize]
339
        mov     eax, [edi+XFS.dirblocksize]
336
        call    malloc
340
        call    malloc
337
        mov     [edi+XFS.cur_dirblock], eax
341
        mov     [edi+XFS.cur_dirblock], eax
338
        test    eax, eax
342
        test    eax, eax
339
        jz      .error
343
        jz      .error
340
 
344
 
341
.quit:
345
.quit:
342
        ; return pointer to allocated XFS partition structure
346
        ; return pointer to allocated XFS partition structure
343
        mov     eax, edi
347
        mov     eax, edi
344
        ret
348
        ret
345
.error:
349
.error:
346
        mov     eax, edi
350
        mov     eax, edi
347
        call    xfs._.free
351
        call    xfs._.free
348
.error_nofree:
352
.error_nofree:
349
        xor     eax, eax
353
        xor     eax, eax
350
        ret
354
        ret
351
endp
355
endp
352
 
356
 
353
 
357
 
354
; lock partition access mutex
358
; lock partition access mutex
355
xfs._.lock:
359
xfs._.lock:
356
        lea     ecx, [ebp+XFS.Lock]
360
        lea     ecx, [ebp+XFS.Lock]
357
        jmp     mutex_lock
361
        jmp     mutex_lock
358
 
362
 
359
 
363
 
360
; unlock partition access mutex
364
; unlock partition access mutex
361
xfs._.unlock:
365
xfs._.unlock:
362
        lea     ecx, [ebp+XFS.Lock]
366
        lea     ecx, [ebp+XFS.Lock]
363
        jmp     mutex_unlock
367
        jmp     mutex_unlock
364
 
368
 
365
 
369
 
366
; free all the allocated memory
370
; free all the allocated memory
367
; called on partition destroy
371
; called on partition destroy
368
; or during failed initialization from xfs_create_partition
372
; or during failed initialization from xfs_create_partition
369
xfs._.free:
373
xfs._.free:
370
        test    eax, eax
374
        test    eax, eax
371
        jz      .done
375
        jz      .done
372
        push    ebx
376
        push    ebx
373
        mov     ebx, eax
377
        mov     ebx, eax
374
 
378
 
375
 
379
 
376
        ; freeing order must correspond the order of
380
        ; freeing order must correspond the order of
377
        ; allocation in xfs_create_partition
381
        ; allocation in xfs_create_partition
378
        mov     eax, [ebx+XFS.cur_block]
382
        mov     eax, [ebx+XFS.cur_block]
379
        test    eax, eax
383
        test    eax, eax
380
        jz      .done
384
        jz      .done
381
        call    free
385
        call    free
382
 
386
 
383
        mov     eax, [ebx+XFS.cur_block_data]
387
        mov     eax, [ebx+XFS.cur_block_data]
384
        test    eax, eax
388
        test    eax, eax
385
        jz      .done
389
        jz      .done
386
        call    free
390
        call    free
387
 
391
 
388
        mov     eax, [ebx+XFS.cur_inode]
392
        mov     eax, [ebx+XFS.cur_inode]
389
        test    eax, eax
393
        test    eax, eax
390
        jz      .done
394
        jz      .done
391
        call    free
395
        call    free
392
 
396
 
393
        mov     eax, [ebx+XFS.tmp_inode]
397
        mov     eax, [ebx+XFS.tmp_inode]
394
        test    eax, eax
398
        test    eax, eax
395
        jz      .done
399
        jz      .done
396
        call    free
400
        call    free
397
 
401
 
398
        mov     eax, [ebx+XFS.cur_sect]
402
        mov     eax, [ebx+XFS.cur_sect]
399
        test    eax, eax
403
        test    eax, eax
400
        jz      .done
404
        jz      .done
401
        call    free
405
        call    free
402
 
406
 
403
        mov     eax, [ebx+XFS.cur_dirblock]
407
        mov     eax, [ebx+XFS.cur_dirblock]
404
        test    eax, eax
408
        test    eax, eax
405
        jz      .done
409
        jz      .done
406
        call    free
410
        call    free
407
 
411
 
408
 
412
 
409
        mov     eax, ebx
413
        mov     eax, ebx
410
        call    free
414
        call    free
411
        pop     ebx
415
        pop     ebx
412
.done:
416
.done:
413
        ret
417
        ret
414
 
418
 
415
 
419
 
416
;---------------------------------------------------------------
420
;---------------------------------------------------------------
417
; block number
421
; block number
418
; eax -- inode_lo
422
; eax -- inode_lo
419
; edx -- inode_hi
423
; edx -- inode_hi
420
; ebx -- buffer
424
; ebx -- buffer
421
;---------------------------------------------------------------
425
;---------------------------------------------------------------
422
proc xfs._.read_block
426
proc xfs._.read_block
423
        movi    ecx, 1
427
        movi    ecx, 1
424
        call    xfs._.read_blocks
428
        call    xfs._.read_blocks
425
        ret
429
        ret
426
endp
430
endp
427
 
431
 
428
 
432
 
429
proc xfs._.blkrel2sectabs uses esi
433
proc xfs._.blkrel2sectabs uses esi
430
        push    edx eax
434
        push    edx eax
431
 
435
 
432
        ; XFS block numbers are AG relative
436
        ; XFS block numbers are AG relative
433
        ; they come in bitfield form of concatenated AG and block numbers
437
        ; they come in bitfield form of concatenated AG and block numbers
434
        ; to get absolute block number for fs_read64_sys we should
438
        ; to get absolute block number for fs_read64_sys we should
435
        ; 1. get AG number and multiply it by the AG size in blocks
439
        ; 1. get AG number and multiply it by the AG size in blocks
436
        ; 2. extract and add AG relative block number
440
        ; 2. extract and add AG relative block number
437
 
441
 
438
        ; 1.
442
        ; 1.
439
        mov     ecx, [ebp+XFS.agblklog]
443
        mov     ecx, [ebp+XFS.agblklog]
440
        shrd    eax, edx, cl
444
        shrd    eax, edx, cl
441
        shr     edx, cl
445
        shr     edx, cl
442
        mul     [ebp+XFS.agblocks]
446
        mul     [ebp+XFS.agblocks]
443
        ; 2.
447
        ; 2.
444
        pop     ecx esi
448
        pop     ecx esi
445
        and     ecx, [ebp+XFS.agblockmask.lo]
449
        and     ecx, [ebp+XFS.agblockmask.lo]
446
        and     esi, [ebp+XFS.agblockmask.hi]
450
        and     esi, [ebp+XFS.agblockmask.hi]
447
        add     eax, ecx
451
        add     eax, ecx
448
        adc     edx, esi
452
        adc     edx, esi
449
 
453
 
450
        mov     ecx, [ebp+XFS.sectpblog]
454
        mov     ecx, [ebp+XFS.sectpblog]
451
        shld    edx, eax, cl
455
        shld    edx, eax, cl
452
        shl     eax, cl
456
        shl     eax, cl
453
        ret
457
        ret
454
endp
458
endp
455
 
459
 
456
 
460
 
457
;---------------------------------------------------------------
461
;---------------------------------------------------------------
458
; start block number
462
; start block number
459
; edx:eax -- block
463
; edx:eax -- block
460
; ebx -- buffer
464
; ebx -- buffer
461
; ecx -- count
465
; ecx -- count
462
;---------------------------------------------------------------
466
;---------------------------------------------------------------
463
proc xfs._.read_blocks
467
proc xfs._.read_blocks
464
        push    ecx
468
        push    ecx
465
        call    xfs._.blkrel2sectabs
469
        call    xfs._.blkrel2sectabs
466
        pop     ecx
470
        pop     ecx
467
        imul    ecx, [ebp+XFS.sectpblock]
471
        imul    ecx, [ebp+XFS.sectpblock]
468
        call    fs_read64_sys
472
        call    fs_read64_sys
469
        test    eax, eax
473
        test    eax, eax
470
        ret
474
        ret
471
endp
475
endp
472
 
476
 
473
 
477
 
474
proc xfs._.read_dirblock uses ebx, _startblock:qword, _buffer
478
proc xfs._.read_dirblock uses ebx, _startblock:qword, _buffer
475
        mov     eax, dword[_startblock+DQ.lo]
479
        mov     eax, dword[_startblock+DQ.lo]
476
        mov     edx, dword[_startblock+DQ.hi]
480
        mov     edx, dword[_startblock+DQ.hi]
477
        mov     ebx, [_buffer]
481
        mov     ebx, [_buffer]
478
        mov     ecx, [ebp+XFS.blkpdirblk]
482
        mov     ecx, [ebp+XFS.blkpdirblk]
479
        call    xfs._.read_blocks
483
        call    xfs._.read_blocks
480
        ret
484
        ret
481
endp
485
endp
482
 
486
 
483
 
487
 
484
;---------------------------------------------------------------
488
;---------------------------------------------------------------
485
; test eax, eax
489
; test eax, eax
486
;---------------------------------------------------------------
490
;---------------------------------------------------------------
487
proc xfs_read_inode uses ebx, _inode_lo, _inode_hi, _buffer
491
proc xfs_read_inode uses ebx, _inode_lo, _inode_hi, _buffer
488
        mov     eax, [_inode_lo]
492
        mov     eax, [_inode_lo]
489
        mov     edx, [_inode_hi]
493
        mov     edx, [_inode_hi]
490
        mov     ebx, [_buffer]
494
        mov     ebx, [_buffer]
491
        ; inodes are packed into blocks
495
        ; inodes are packed into blocks
492
        ; 1. calculate block number
496
        ; 1. calculate block number
493
        ; 2. read the block
497
        ; 2. read the block
494
        ; 3. add inode offset to block base address
498
        ; 3. add inode offset to block base address
495
        ; 1.
499
        ; 1.
496
        mov     ecx, [ebp+XFS.inopblog]
500
        mov     ecx, [ebp+XFS.inopblog]
497
        shrd    eax, edx, cl
501
        shrd    eax, edx, cl
498
        shr     edx, cl
502
        shr     edx, cl
499
        ; 2.
503
        ; 2.
500
        call    xfs._.read_block
504
        call    xfs._.read_block
501
        jnz     .error
505
        jnz     .error
502
        ; inode numbers should be first extracted from bitfields by mask
506
        ; inode numbers should be first extracted from bitfields by mask
503
 
507
 
504
        mov     eax, [_inode_lo]
508
        mov     eax, [_inode_lo]
505
        mov     edx, 1
509
        mov     edx, 1
506
        mov     ecx, [ebp+XFS.inopblog]
510
        mov     ecx, [ebp+XFS.inopblog]
507
        shl     edx, cl
511
        shl     edx, cl
508
        dec     edx             ; get inode number mask
512
        dec     edx             ; get inode number mask
509
        and     eax, edx        ; apply mask
513
        and     eax, edx        ; apply mask
510
        mov     ecx, [ebp+XFS.inodelog]
514
        mov     ecx, [ebp+XFS.inodelog]
511
        shl     eax, cl
515
        shl     eax, cl
512
        add     ebx, eax
516
        add     ebx, eax
513
        xor     eax, eax
517
        xor     eax, eax
514
 
518
 
515
        cmp     [ebx+xfs_inode.di_core.di_magic], XFS_DINODE_MAGIC
519
        cmp     [ebx+xfs_inode.di_core.di_magic], XFS_DINODE_MAGIC
516
        jz      .quit
520
        jz      .quit
517
        movi    eax, ERROR_FS_FAIL
521
        movi    eax, ERROR_FS_FAIL
518
.quit:
522
.quit:
519
        mov     edx, ebx
523
        mov     edx, ebx
520
.error:
524
.error:
521
        ret
525
        ret
522
endp
526
endp
523
 
527
 
524
 
528
 
525
; skip ecx first entries
529
; skip ecx first entries
526
proc xfs._.dir_sf_skip _count
530
proc xfs._.dir_sf_skip _count
527
        mov     ecx, [_count]
531
        mov     ecx, [_count]
528
.next:
532
.next:
529
        dec     ecx
533
        dec     ecx
530
        js      .quit
534
        js      .quit
531
        dec     [ebp+XFS.entries_left_in_dir]
535
        dec     [ebp+XFS.entries_left_in_dir]
532
        js      .quit
536
        js      .quit
533
.self:
537
.self:
534
        bts     [ebp+XFS.dir_sf_self_done], 0
538
        bts     [ebp+XFS.dir_sf_self_done], 0
535
        jc      .parent
539
        jc      .parent
536
        jmp     .next
540
        jmp     .next
537
.parent:
541
.parent:
538
        bts     [ebp+XFS.dir_sf_parent_done], 0
542
        bts     [ebp+XFS.dir_sf_parent_done], 0
539
        jc      .common
543
        jc      .common
540
        jmp     .next
544
        jmp     .next
541
.common:
545
.common:
542
        movzx   eax, [esi+xfs_dir2_sf_entry.namelen]
546
        movzx   eax, [esi+xfs_dir2_sf_entry.namelen]
543
        add     esi, xfs_dir2_sf_entry.name
547
        add     esi, xfs_dir2_sf_entry.name
544
        add     esi, eax
548
        add     esi, eax
545
        add     esi, [ebp+XFS.ftype_size]
549
        add     esi, [ebp+XFS.ftype_size]
546
        add     esi, [ebp+XFS.shortform_inodelen]
550
        add     esi, [ebp+XFS.shortform_inodelen]
547
        jmp     .next
551
        jmp     .next
548
.quit:
552
.quit:
549
        ret
553
        ret
550
endp
554
endp
551
 
555
 
552
 
556
 
553
proc xfs._.dir_sf_read uses edi, _count
557
proc xfs._.dir_sf_read uses edi, _count
554
locals
558
locals
555
        _dst dd ?
559
        _dst dd ?
556
endl
560
endl
557
.next:
561
.next:
558
        dec     [_count]
562
        dec     [_count]
559
        js      .quit
563
        js      .quit
560
        dec     [ebp+XFS.entries_left_in_dir]
564
        dec     [ebp+XFS.entries_left_in_dir]
561
        js      .quit
565
        js      .quit
562
        mov     [_dst], edx
566
        mov     [_dst], edx
563
.self:
567
.self:
564
        bts     [ebp+XFS.dir_sf_self_done], 0
568
        bts     [ebp+XFS.dir_sf_self_done], 0
565
        jc      .parent
569
        jc      .parent
566
        lea     edi, [edx+bdfe.name]
570
        lea     edi, [edx+bdfe.name]
567
        mov     dword[edi], '.'
571
        mov     dword[edi], '.'
568
        stdcall xfs_get_inode_info, [ebp+XFS.cur_inode], edx
572
        stdcall xfs_get_inode_info, [ebp+XFS.cur_inode], edx
569
        jmp     .common
573
        jmp     .common
570
.parent:
574
.parent:
571
        bts     [ebp+XFS.dir_sf_parent_done], 0
575
        bts     [ebp+XFS.dir_sf_parent_done], 0
572
        jc      .not_special
576
        jc      .not_special
573
        lea     edi, [edx+bdfe.name]         ; get file name offset
577
        lea     edi, [edx+bdfe.name]         ; get file name offset
574
        mov     dword[edi], '..'        ; terminator included
578
        mov     dword[edi], '..'        ; terminator included
575
        mov     edi, edx
579
        mov     edi, edx
576
        lea     edx, [ebx+xfs_dir2_sf.hdr.parent]
580
        lea     edx, [ebx+xfs_dir2_sf.hdr.parent]
577
        call    xfs._.get_inode_number_sf
581
        call    xfs._.get_inode_number_sf
578
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.tmp_inode]
582
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.tmp_inode]
579
        test    eax, eax
583
        test    eax, eax
580
        jnz     .error
584
        jnz     .error
581
        stdcall xfs_get_inode_info, edx, edi
585
        stdcall xfs_get_inode_info, edx, edi
582
        jmp     .common
586
        jmp     .common
583
.not_special:
587
.not_special:
584
        movzx   ecx, [esi+xfs_dir2_sf_entry.namelen]
588
        movzx   ecx, [esi+xfs_dir2_sf_entry.namelen]
585
        add     esi, xfs_dir2_sf_entry.name
589
        add     esi, xfs_dir2_sf_entry.name
586
        lea     edi, [edx+bdfe.name]
590
        lea     edi, [edx+bdfe.name]
587
        stdcall xfs._.copy_filename
591
        stdcall xfs._.copy_filename
588
        add     esi, [ebp+XFS.ftype_size]
592
        add     esi, [ebp+XFS.ftype_size]
589
        mov     edi, edx
593
        mov     edi, edx
590
        mov     edx, esi
594
        mov     edx, esi
591
        call    xfs._.get_inode_number_sf
595
        call    xfs._.get_inode_number_sf
592
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.tmp_inode]
596
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.tmp_inode]
593
        test    eax, eax
597
        test    eax, eax
594
        jnz     .error
598
        jnz     .error
595
        stdcall xfs_get_inode_info, edx, edi
599
        stdcall xfs_get_inode_info, edx, edi
596
        add     esi, [ebp+XFS.shortform_inodelen]
600
        add     esi, [ebp+XFS.shortform_inodelen]
597
.common:
601
.common:
598
        mov     edx, [_dst]
602
        mov     edx, [_dst]
599
        mov     eax, [ebp+XFS.bdfe_nameenc]
603
        mov     eax, [ebp+XFS.bdfe_nameenc]
600
        mov     [edx+bdfe.nameenc], eax
604
        mov     [edx+bdfe.nameenc], eax
601
        add     edx, [ebp+XFS.bdfe_len]
605
        add     edx, [ebp+XFS.bdfe_len]
602
        inc     [ebp+XFS.entries_read]
606
        inc     [ebp+XFS.entries_read]
603
        jmp     .next
607
        jmp     .next
604
.quit:
608
.quit:
605
        xor     eax, eax
609
        xor     eax, eax
606
.error:
610
.error:
607
        ret
611
        ret
608
endp
612
endp
609
 
613
 
610
 
614
 
611
proc xfs._.readdir_sf uses esi, _src, _dst
615
proc xfs._.readdir_sf uses esi, _src, _dst
612
        mov     ebx, [_src]
616
        mov     ebx, [_src]
613
        mov     edx, [_dst]
617
        mov     edx, [_dst]
614
        mov     [ebp+XFS.dir_sf_self_done], 0
618
        mov     [ebp+XFS.dir_sf_self_done], 0
615
        mov     [ebp+XFS.dir_sf_parent_done], 0
619
        mov     [ebp+XFS.dir_sf_parent_done], 0
616
        mov     [ebp+XFS.entries_read], 0
620
        mov     [ebp+XFS.entries_read], 0
617
        movzx   eax, [ebx+xfs_dir2_sf.hdr.count]
621
        movzx   eax, [ebx+xfs_dir2_sf.hdr.count]
618
        ; '..' and '.' are implicit
622
        ; '..' and '.' are implicit
619
        add     eax, 2
623
        add     eax, 2
620
        mov     [ebp+XFS.entries_left_in_dir], eax
624
        mov     [ebp+XFS.entries_left_in_dir], eax
621
        mov     [edx+bdfe_hdr.total_cnt], eax
625
        mov     [edx+bdfe_hdr.total_cnt], eax
622
        ; inode numbers are often saved as 4 bytes (iff they fit)
626
        ; inode numbers are often saved as 4 bytes (iff they fit)
623
        ; compute the length of inode numbers
627
        ; compute the length of inode numbers
624
        ; 8 iff i8count != 0, 4 otherwise
628
        ; 8 iff i8count != 0, 4 otherwise
625
        cmp     [ebx+xfs_dir2_sf.hdr.i8count], 0
629
        cmp     [ebx+xfs_dir2_sf.hdr.i8count], 0
626
        setnz   al
630
        setnz   al
627
        lea     eax, [eax*4+4]
631
        lea     eax, [eax*4+4]
628
        mov     [ebp+XFS.shortform_inodelen], eax
632
        mov     [ebp+XFS.shortform_inodelen], eax
629
        add     edx, sizeof.bdfe_hdr
633
        add     edx, sizeof.bdfe_hdr
630
        lea     esi, [ebx+xfs_dir2_sf.hdr.parent+eax]
634
        lea     esi, [ebx+xfs_dir2_sf.hdr.parent+eax]
631
        stdcall xfs._.dir_sf_skip, [ebp+XFS.entries_to_skip]
635
        stdcall xfs._.dir_sf_skip, [ebp+XFS.entries_to_skip]
632
        stdcall xfs._.dir_sf_read, [ebp+XFS.requested_cnt]
636
        stdcall xfs._.dir_sf_read, [ebp+XFS.requested_cnt]
633
        ret
637
        ret
634
endp
638
endp
635
 
639
 
636
 
640
 
637
proc xfs._.readdir_block _literal_area, _out_buf
641
proc xfs._.readdir_block _literal_area, _out_buf
638
        mov     ebx, [_literal_area]
642
        mov     ebx, [_literal_area]
639
        mov     [ebp+XFS.entries_read], 0
643
        mov     [ebp+XFS.entries_read], 0
640
        mov     eax, ebx
644
        mov     eax, ebx
641
        mov     ebx, [ebp+XFS.cur_dirblock]
645
        mov     ebx, [ebp+XFS.cur_dirblock]
642
        stdcall xfs._.extent_unpack, eax
646
        stdcall xfs._.extent_unpack, eax
643
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], ebx
647
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], ebx
644
        mov     edx, [_out_buf]
648
        mov     edx, [_out_buf]
645
        jnz     .error
649
        jnz     .error
646
        mov     eax, [ebp+XFS.dir_block_magic]
650
        mov     eax, [ebp+XFS.dir_block_magic]
647
        cmp     [ebx+xfs_dir2_block.hdr.magic], eax
651
        cmp     [ebx+xfs_dir2_block.hdr.magic], eax
648
        movi    eax, ERROR_FS_FAIL
652
        movi    eax, ERROR_FS_FAIL
649
        jnz     .error
653
        jnz     .error
650
        mov     eax, [ebp+XFS.dirblocksize]
654
        mov     eax, [ebp+XFS.dirblocksize]
651
        movbe   ecx, [ebx+eax-sizeof.xfs_dir2_block_tail+xfs_dir2_block_tail.stale]
655
        movbe   ecx, [ebx+eax-sizeof.xfs_dir2_block_tail+xfs_dir2_block_tail.stale]
652
        movbe   eax, [ebx+eax-sizeof.xfs_dir2_block_tail+xfs_dir2_block_tail.count]
656
        movbe   eax, [ebx+eax-sizeof.xfs_dir2_block_tail+xfs_dir2_block_tail.count]
653
        sub     eax, ecx        ; actual number of entries = count - stale
657
        sub     eax, ecx        ; actual number of entries = count - stale
654
        mov     [ebp+XFS.entries_left_in_dir], eax
658
        mov     [ebp+XFS.entries_left_in_dir], eax
655
        mov     [edx+bdfe_hdr.total_cnt], eax
659
        mov     [edx+bdfe_hdr.total_cnt], eax
656
 
660
 
657
        add     ebx, [ebp+XFS.dir_block_size]
661
        add     ebx, [ebp+XFS.dir_block_size]
658
        add     edx, sizeof.bdfe_hdr
662
        add     edx, sizeof.bdfe_hdr
659
        mov     [_out_buf], edx
663
        mov     [_out_buf], edx
660
        lea     edi, [_out_buf]
664
        lea     edi, [_out_buf]
661
.next:
665
.next:
662
        movi    eax, ERROR_SUCCESS
666
        movi    eax, ERROR_SUCCESS
663
        cmp     [ebp+XFS.requested_cnt], 0
667
        cmp     [ebp+XFS.requested_cnt], 0
664
        jz      .quit
668
        jz      .quit
665
        cmp     [ebp+XFS.entries_left_in_dir], 0
669
        cmp     [ebp+XFS.entries_left_in_dir], 0
666
        jz      .quit
670
        jz      .quit
667
        stdcall xfs._.dir_entry_skip_read, edi
671
        stdcall xfs._.dir_entry_skip_read, edi
668
        jz      .next
672
        jz      .next
669
.error:
673
.error:
670
.quit:
674
.quit:
671
        ret
675
        ret
672
endp
676
endp
673
 
677
 
674
 
678
 
675
proc xfs._.readdir_leaf_node uses esi, _inode_data, _out_buf
679
proc xfs._.readdir_leaf_node uses esi, _inode_data, _out_buf
676
        mov     ebx, [_inode_data]
680
        mov     ebx, [_inode_data]
677
        mov     edx, [_out_buf]
681
        mov     edx, [_out_buf]
678
        mov     [ebp+XFS.cur_inode_save], ebx
682
        mov     [ebp+XFS.cur_inode_save], ebx
679
        mov     [ebp+XFS.entries_read], 0
683
        mov     [ebp+XFS.entries_read], 0
680
        mov     eax, ebx
684
        mov     eax, ebx
681
        add     eax, [ebp+XFS.inode_core_size]
685
        add     eax, [ebp+XFS.inode_core_size]
682
        mov     edx, [ebp+XFS.nextents_offset]
686
        mov     edx, [ebp+XFS.nextents_offset]
683
        movbe   edx, [ebx+edx]
687
        movbe   edx, [ebx+edx]
684
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.lo]
688
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.lo]
685
        mov     [ebp+XFS.offset_begin.lo], ecx
689
        mov     [ebp+XFS.offset_begin.lo], ecx
686
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.hi]
690
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.hi]
687
        mov     [ebp+XFS.offset_begin.hi], ecx
691
        mov     [ebp+XFS.offset_begin.hi], ecx
688
        mov     ecx, [ebp+XFS.dir2_free_offset_blocks.lo]
692
        mov     ecx, [ebp+XFS.dir2_free_offset_blocks.lo]
689
        mov     [ebp+XFS.offset_end.lo], ecx
693
        mov     [ebp+XFS.offset_end.lo], ecx
690
        mov     ecx, [ebp+XFS.dir2_free_offset_blocks.hi]
694
        mov     ecx, [ebp+XFS.dir2_free_offset_blocks.hi]
691
        mov     [ebp+XFS.offset_end.hi], ecx
695
        mov     [ebp+XFS.offset_end.hi], ecx
692
        stdcall xfs._.walk_extent_list, edx, eax, xfs._.extent_iterate_dirblocks, xfs._.leafn_calc_entries, 0
696
        stdcall xfs._.walk_extent_list, edx, eax, xfs._.extent_iterate_dirblocks, xfs._.leafn_calc_entries, 0
693
        jnz     .error
697
        jnz     .error
694
        mov     eax, [ebp+XFS.entries_read]
698
        mov     eax, [ebp+XFS.entries_read]
695
        mov     edx, [_out_buf]
699
        mov     edx, [_out_buf]
696
        mov     [edx+bdfe_hdr.total_cnt], eax
700
        mov     [edx+bdfe_hdr.total_cnt], eax
697
        mov     [ebp+XFS.entries_left_in_dir], eax
701
        mov     [ebp+XFS.entries_left_in_dir], eax
698
        add     [_out_buf], sizeof.bdfe_hdr
702
        add     [_out_buf], sizeof.bdfe_hdr
699
        mov     [ebp+XFS.entries_read], 0
703
        mov     [ebp+XFS.entries_read], 0
700
        mov     edx, [ebp+XFS.nextents_offset]
704
        mov     edx, [ebp+XFS.nextents_offset]
701
        movbe   edx, [ebx+edx]
705
        movbe   edx, [ebx+edx]
702
        mov     eax, ebx
706
        mov     eax, ebx
703
        add     eax, [ebp+XFS.inode_core_size]
707
        add     eax, [ebp+XFS.inode_core_size]
704
        lea     ecx, [_out_buf]
708
        lea     ecx, [_out_buf]
705
        push    ecx
709
        push    ecx
706
        mov     [ebp+XFS.offset_begin.lo], 0
710
        mov     [ebp+XFS.offset_begin.lo], 0
707
        mov     [ebp+XFS.offset_begin.hi], 0
711
        mov     [ebp+XFS.offset_begin.hi], 0
708
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.lo]
712
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.lo]
709
        mov     [ebp+XFS.offset_end.lo], ecx
713
        mov     [ebp+XFS.offset_end.lo], ecx
710
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.hi]
714
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.hi]
711
        mov     [ebp+XFS.offset_end.hi], ecx
715
        mov     [ebp+XFS.offset_end.hi], ecx
712
        pop     ecx
716
        pop     ecx
713
        stdcall xfs._.walk_extent_list, edx, eax, xfs._.extent_iterate_dirblocks, xfs._.dir_btree_skip_read, ecx
717
        stdcall xfs._.walk_extent_list, edx, eax, xfs._.extent_iterate_dirblocks, xfs._.dir_btree_skip_read, ecx
714
;        jnz     .error
718
;        jnz     .error
715
.error:
719
.error:
716
.quit:
720
.quit:
717
        ret
721
        ret
718
endp
722
endp
719
 
723
 
720
 
724
 
721
proc xfs._.dir_entry_skip_read uses esi edi, _arg
725
proc xfs._.dir_entry_skip_read uses esi edi, _arg
722
        cmp     [ebx+xfs_dir2_data_union.unused.freetag], XFS_NULL
726
        cmp     [ebx+xfs_dir2_data_union.unused.freetag], XFS_NULL
723
        jnz     @f
727
        jnz     @f
724
        movzx   eax, [ebx+xfs_dir2_data_union.unused.length]
728
        movzx   eax, [ebx+xfs_dir2_data_union.unused.length]
725
        xchg    al, ah
729
        xchg    al, ah
726
        add     ebx, eax
730
        add     ebx, eax
727
        jmp     .quit
731
        jmp     .quit
728
@@:
732
@@:
729
        cmp     [ebp+XFS.entries_to_skip], 0
733
        cmp     [ebp+XFS.entries_to_skip], 0
730
        jz      .read
734
        jz      .read
731
.skip:
735
.skip:
732
        dec     [ebp+XFS.entries_to_skip]
736
        dec     [ebp+XFS.entries_to_skip]
733
        movzx   ecx, [ebx+xfs_dir2_data_union.xentry.namelen]
737
        movzx   ecx, [ebx+xfs_dir2_data_union.xentry.namelen]
734
        lea     ebx, [ebx+xfs_dir2_data_union.xentry.name+ecx+2]
738
        lea     ebx, [ebx+xfs_dir2_data_union.xentry.name+ecx+2]
735
        add     ebx, [ebp+XFS.ftype_size]
739
        add     ebx, [ebp+XFS.ftype_size]
736
        jmp     .common
740
        jmp     .common
737
.read:
741
.read:
738
        dec     [ebp+XFS.requested_cnt]
742
        dec     [ebp+XFS.requested_cnt]
739
        inc     [ebp+XFS.entries_read]
743
        inc     [ebp+XFS.entries_read]
740
        mov     edi, [_arg]
744
        mov     edi, [_arg]
741
        mov     edi, [edi]
745
        mov     edi, [edi]
742
        movbe   edx, [ebx+xfs_dir2_data_union.xentry.inumber.lo]
746
        movbe   edx, [ebx+xfs_dir2_data_union.xentry.inumber.lo]
743
        movbe   eax, [ebx+xfs_dir2_data_union.xentry.inumber.hi]
747
        movbe   eax, [ebx+xfs_dir2_data_union.xentry.inumber.hi]
744
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.tmp_inode]
748
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.tmp_inode]
745
        stdcall xfs_get_inode_info, edx, edi
749
        stdcall xfs_get_inode_info, edx, edi
746
        jnz     .error
750
        jnz     .error
747
        mov     edx, [_arg]
751
        mov     edx, [_arg]
748
        mov     edx, [edx]
752
        mov     edx, [edx]
749
        mov     ecx, [ebp+XFS.bdfe_nameenc]
753
        mov     ecx, [ebp+XFS.bdfe_nameenc]
750
        mov     [edx+bdfe.nameenc], ecx
754
        mov     [edx+bdfe.nameenc], ecx
751
        lea     edi, [edx+bdfe.name]
755
        lea     edi, [edx+bdfe.name]
752
        movzx   ecx, [ebx+xfs_dir2_data_union.xentry.namelen]
756
        movzx   ecx, [ebx+xfs_dir2_data_union.xentry.namelen]
753
        lea     esi, [ebx+xfs_dir2_data_union.xentry.name]
757
        lea     esi, [ebx+xfs_dir2_data_union.xentry.name]
754
        stdcall xfs._.copy_filename
758
        stdcall xfs._.copy_filename
755
        lea     ebx, [esi+2]  ; skip 'tag'
759
        lea     ebx, [esi+2]  ; skip 'tag'
756
        add     ebx, [ebp+XFS.ftype_size]
760
        add     ebx, [ebp+XFS.ftype_size]
757
        mov     eax, [_arg]
761
        mov     eax, [_arg]
758
        mov     edx, [eax]
762
        mov     edx, [eax]
759
        add     edx, [ebp+XFS.bdfe_len]
763
        add     edx, [ebp+XFS.bdfe_len]
760
        mov     [eax], edx
764
        mov     [eax], edx
761
.common:
765
.common:
762
        sub     ebx, [ebp+XFS.cur_dirblock]
766
        sub     ebx, [ebp+XFS.cur_dirblock]
763
        add     ebx, 7          ; xfs_dir2_data_entries are aligned to 8 bytes
767
        add     ebx, 7          ; xfs_dir2_data_entries are aligned to 8 bytes
764
        and     ebx, not 7
768
        and     ebx, not 7
765
        add     ebx, [ebp+XFS.cur_dirblock]
769
        add     ebx, [ebp+XFS.cur_dirblock]
766
        dec     [ebp+XFS.entries_left_in_dir]
770
        dec     [ebp+XFS.entries_left_in_dir]
767
.quit:
771
.quit:
768
        movi    eax, ERROR_SUCCESS
772
        movi    eax, ERROR_SUCCESS
769
        cmp     esp, esp
773
        cmp     esp, esp
770
.error:
774
.error:
771
        ret
775
        ret
772
endp
776
endp
773
 
777
 
774
 
778
 
775
proc xfs._.dir_btree_skip_read uses ebx ecx edx esi edi, _cur_dirblock, _offset_lo, _offset_hi, _arg
779
proc xfs._.dir_btree_skip_read uses ebx ecx edx esi edi, _cur_dirblock, _offset_lo, _offset_hi, _arg
776
        mov     ebx, [_cur_dirblock]
780
        mov     ebx, [_cur_dirblock]
777
        mov     eax, [ebp+XFS.dir_data_magic]
781
        mov     eax, [ebp+XFS.dir_data_magic]
778
        cmp     [ebx+xfs_dir2_block.hdr.magic], eax
782
        cmp     [ebx+xfs_dir2_block.hdr.magic], eax
779
        movi    eax, ERROR_FS_FAIL
783
        movi    eax, ERROR_FS_FAIL
780
        jnz     .error
784
        jnz     .error
781
        mov     eax, ebx
785
        mov     eax, ebx
782
        add     eax, [ebp+XFS.dirblocksize]
786
        add     eax, [ebp+XFS.dirblocksize]
783
        mov     [ebp+XFS.max_dirblockaddr], eax
787
        mov     [ebp+XFS.max_dirblockaddr], eax
784
        add     ebx, [ebp+XFS.dir_block_size]
788
        add     ebx, [ebp+XFS.dir_block_size]
785
.next:
789
.next:
786
        movi    eax, ERROR_SUCCESS
790
        movi    eax, ERROR_SUCCESS
787
        cmp     [ebp+XFS.requested_cnt], 0
791
        cmp     [ebp+XFS.requested_cnt], 0
788
        jz      .quit
792
        jz      .quit
789
        cmp     [ebp+XFS.entries_left_in_dir], 0
793
        cmp     [ebp+XFS.entries_left_in_dir], 0
790
        jz      .quit
794
        jz      .quit
791
        cmp     ebx, [ebp+XFS.max_dirblockaddr]
795
        cmp     ebx, [ebp+XFS.max_dirblockaddr]
792
        jz      .quit
796
        jz      .quit
793
        stdcall xfs._.dir_entry_skip_read, [_arg]
797
        stdcall xfs._.dir_entry_skip_read, [_arg]
794
        jz      .next
798
        jz      .next
795
.error:
799
.error:
796
.quit:
800
.quit:
797
        ret
801
        ret
798
endp
802
endp
799
 
803
 
800
 
804
 
801
proc xfs._.readdir_btree uses esi, _inode_data, _out_buf
805
proc xfs._.readdir_btree uses esi, _inode_data, _out_buf
802
        mov     [ebp+XFS.cur_inode_save], ebx
806
        mov     [ebp+XFS.cur_inode_save], ebx
803
        mov     [ebp+XFS.entries_read], 0
807
        mov     [ebp+XFS.entries_read], 0
804
        mov     eax, [ebp+XFS.inodesize]
808
        mov     eax, [ebp+XFS.inodesize]
805
        sub     eax, [ebp+XFS.inode_core_size]
809
        sub     eax, [ebp+XFS.inode_core_size]
806
        movzx   ecx, [ebx+xfs_inode.di_core.di_forkoff]
810
        movzx   ecx, [ebx+xfs_inode.di_core.di_forkoff]
807
        jecxz   @f
811
        jecxz   @f
808
        shl     ecx, 3
812
        shl     ecx, 3
809
        mov     eax, ecx
813
        mov     eax, ecx
810
@@:
814
@@:
811
        mov     edx, ebx
815
        mov     edx, ebx
812
        add     edx, [ebp+XFS.inode_core_size]
816
        add     edx, [ebp+XFS.inode_core_size]
813
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.lo]
817
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.lo]
814
        mov     [ebp+XFS.offset_begin.lo], ecx
818
        mov     [ebp+XFS.offset_begin.lo], ecx
815
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.hi]
819
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.hi]
816
        mov     [ebp+XFS.offset_begin.hi], ecx
820
        mov     [ebp+XFS.offset_begin.hi], ecx
817
        mov     ecx, [ebp+XFS.dir2_free_offset_blocks.lo]
821
        mov     ecx, [ebp+XFS.dir2_free_offset_blocks.lo]
818
        mov     [ebp+XFS.offset_end.lo], ecx
822
        mov     [ebp+XFS.offset_end.lo], ecx
819
        mov     ecx, [ebp+XFS.dir2_free_offset_blocks.hi]
823
        mov     ecx, [ebp+XFS.dir2_free_offset_blocks.hi]
820
        mov     [ebp+XFS.offset_end.hi], ecx
824
        mov     [ebp+XFS.offset_end.hi], ecx
821
        stdcall xfs._.walk_btree, edx, eax, xfs._.extent_iterate_dirblocks, xfs._.leafn_calc_entries, 0, 1
825
        stdcall xfs._.walk_btree, edx, eax, xfs._.extent_iterate_dirblocks, xfs._.leafn_calc_entries, 0, 1
822
        mov     eax, [ebp+XFS.entries_read]
826
        mov     eax, [ebp+XFS.entries_read]
823
        mov     edx, [_out_buf]
827
        mov     edx, [_out_buf]
824
        mov     [edx+bdfe_hdr.total_cnt], eax
828
        mov     [edx+bdfe_hdr.total_cnt], eax
825
        mov     [ebp+XFS.entries_left_in_dir], eax
829
        mov     [ebp+XFS.entries_left_in_dir], eax
826
        mov     [ebp+XFS.entries_read], 0
830
        mov     [ebp+XFS.entries_read], 0
827
        add     [_out_buf], sizeof.bdfe_hdr
831
        add     [_out_buf], sizeof.bdfe_hdr
828
        mov     eax, [ebp+XFS.inodesize]
832
        mov     eax, [ebp+XFS.inodesize]
829
        sub     eax, [ebp+XFS.inode_core_size]
833
        sub     eax, [ebp+XFS.inode_core_size]
830
        movzx   ecx, [ebx+xfs_inode.di_core.di_forkoff]
834
        movzx   ecx, [ebx+xfs_inode.di_core.di_forkoff]
831
        jecxz   @f
835
        jecxz   @f
832
        shl     ecx, 3
836
        shl     ecx, 3
833
        mov     eax, ecx
837
        mov     eax, ecx
834
@@:
838
@@:
835
        mov     edx, ebx
839
        mov     edx, ebx
836
        add     edx, [ebp+XFS.inode_core_size]
840
        add     edx, [ebp+XFS.inode_core_size]
837
        mov     [ebp+XFS.offset_begin.lo], 0
841
        mov     [ebp+XFS.offset_begin.lo], 0
838
        mov     [ebp+XFS.offset_begin.hi], 0
842
        mov     [ebp+XFS.offset_begin.hi], 0
839
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.lo]
843
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.lo]
840
        mov     [ebp+XFS.offset_end.lo], ecx
844
        mov     [ebp+XFS.offset_end.lo], ecx
841
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.hi]
845
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.hi]
842
        mov     [ebp+XFS.offset_end.hi], ecx
846
        mov     [ebp+XFS.offset_end.hi], ecx
843
        mov     ecx, [_out_buf]
847
        mov     ecx, [_out_buf]
844
        push    ecx
848
        push    ecx
845
        mov     ecx, esp
849
        mov     ecx, esp
846
        stdcall xfs._.walk_btree, edx, eax, xfs._.extent_iterate_dirblocks, xfs._.dir_btree_skip_read, ecx, 1
850
        stdcall xfs._.walk_btree, edx, eax, xfs._.extent_iterate_dirblocks, xfs._.dir_btree_skip_read, ecx, 1
847
        pop     ecx
851
        pop     ecx
848
.error:
852
.error:
849
.quit:
853
.quit:
850
        ret
854
        ret
851
endp
855
endp
852
 
856
 
853
 
857
 
854
proc xfs._.copy_filename uses eax
858
proc xfs._.copy_filename uses eax
855
        mov     eax, [ebp+XFS.bdfe_nameenc]
859
        mov     eax, [ebp+XFS.bdfe_nameenc]
856
        cmp     eax, 3
860
        cmp     eax, 3
857
        jz      .utf8
861
        jz      .utf8
858
        cmp     eax, 2
862
        cmp     eax, 2
859
        jz      .utf16
863
        jz      .utf16
860
.cp866:
864
.cp866:
861
        call    unicode.utf8.decode
865
        call    unicode.utf8.decode
862
        call    unicode.cp866.encode
866
        call    unicode.cp866.encode
863
        stosb
867
        stosb
864
        test    ecx, ecx
868
        test    ecx, ecx
865
        jnz     .cp866
869
        jnz     .cp866
866
        mov     byte[edi], 0
870
        mov     byte[edi], 0
867
        jmp     .done
871
        jmp     .done
868
.utf16:
872
.utf16:
869
        call    unicode.utf8.decode
873
        call    unicode.utf8.decode
870
        call    unicode.utf16.encode
874
        call    unicode.utf16.encode
871
        stosw
875
        stosw
872
        shr     eax, 16
876
        shr     eax, 16
873
        jz      @f
877
        jz      @f
874
        stosw
878
        stosw
875
@@:
879
@@:
876
        test    ecx, ecx
880
        test    ecx, ecx
877
        jnz     .utf16
881
        jnz     .utf16
878
        mov     word[edi], 0
882
        mov     word[edi], 0
879
        jmp     .done
883
        jmp     .done
880
.utf8:
884
.utf8:
881
        rep movsb
885
        rep movsb
882
        mov     byte[edi], 0
886
        mov     byte[edi], 0
883
.done:
887
.done:
884
        ret
888
        ret
885
endp
889
endp
886
 
890
 
887
;----------------------------------------------------------------
891
;----------------------------------------------------------------
888
; src              ; inode
892
; src              ; inode
889
; dst              ; bdfe
893
; dst              ; bdfe
890
; start_number     ; from 0
894
; start_number     ; from 0
891
;----------------------------------------------------------------
895
;----------------------------------------------------------------
892
proc xfs._.readdir uses ebx esi edi, _start_number, _entries_to_read, _dst, _src, _encoding
896
proc xfs._.readdir uses ebx esi edi, _start_number, _entries_to_read, _dst, _src, _encoding
893
        mov     ecx, [_start_number]
897
        mov     ecx, [_start_number]
894
        mov     [ebp+XFS.entries_to_skip], ecx
898
        mov     [ebp+XFS.entries_to_skip], ecx
895
        mov     eax, [_entries_to_read]
899
        mov     eax, [_entries_to_read]
896
        mov     [ebp+XFS.requested_cnt], eax
900
        mov     [ebp+XFS.requested_cnt], eax
897
        mov     eax, [_encoding]
901
        mov     eax, [_encoding]
898
        mov     [ebp+XFS.bdfe_nameenc], eax
902
        mov     [ebp+XFS.bdfe_nameenc], eax
899
        mov     ecx, 304
903
        mov     ecx, 304
900
        cmp     eax, 1  ; CP866
904
        cmp     eax, 1  ; CP866
901
        jbe     @f
905
        jbe     @f
902
        mov     ecx, 560
906
        mov     ecx, 560
903
@@:
907
@@:
904
        mov     [ebp+XFS.bdfe_len], ecx
908
        mov     [ebp+XFS.bdfe_len], ecx
905
        mov     edx, [_dst]
909
        mov     edx, [_dst]
906
        mov     [ebp+XFS.bdfe_buf], edx
910
        mov     [ebp+XFS.bdfe_buf], edx
907
        mov     ebx, [_src]
911
        mov     ebx, [_src]
908
        mov     [ebp+XFS.cur_inode_save], ebx
912
        mov     [ebp+XFS.cur_inode_save], ebx
909
 
913
 
910
        mov     [edx+bdfe_hdr.version], 1
914
        mov     [edx+bdfe_hdr.version], 1
911
        mov     [edx+bdfe_hdr.zeroed+0x00], 0
915
        mov     [edx+bdfe_hdr.zeroed+0x00], 0
912
        mov     [edx+bdfe_hdr.zeroed+0x04], 0
916
        mov     [edx+bdfe_hdr.zeroed+0x04], 0
913
        mov     [edx+bdfe_hdr.zeroed+0x08], 0
917
        mov     [edx+bdfe_hdr.zeroed+0x08], 0
914
        mov     [edx+bdfe_hdr.zeroed+0x0c], 0
918
        mov     [edx+bdfe_hdr.zeroed+0x0c], 0
915
        mov     [edx+bdfe_hdr.zeroed+0x10], 0
919
        mov     [edx+bdfe_hdr.zeroed+0x10], 0
916
 
920
 
917
        movzx   eax, [ebx+xfs_inode.di_core.di_format]
921
        movzx   eax, [ebx+xfs_inode.di_core.di_format]
918
        ; switch directory ondisk format and jump to corresponding label
922
        ; switch directory ondisk format and jump to corresponding label
919
        cmp     eax, XFS_DINODE_FMT_LOCAL
923
        cmp     eax, XFS_DINODE_FMT_LOCAL
920
        jnz     @f
924
        jnz     @f
921
        add     ebx, [ebp+XFS.inode_core_size]
925
        add     ebx, [ebp+XFS.inode_core_size]
922
        stdcall xfs._.readdir_sf, ebx, [_dst]
926
        stdcall xfs._.readdir_sf, ebx, [_dst]
923
        test    eax, eax
927
        test    eax, eax
924
        jnz     .error
928
        jnz     .error
925
        jmp     .quit
929
        jmp     .quit
926
@@:
930
@@:
927
        cmp     eax, XFS_DINODE_FMT_BTREE
931
        cmp     eax, XFS_DINODE_FMT_BTREE
928
        jnz     @f
932
        jnz     @f
929
        stdcall xfs._.readdir_btree, ebx, [_dst]
933
        stdcall xfs._.readdir_btree, ebx, [_dst]
930
        jmp     .quit
934
        jmp     .quit
931
@@:
935
@@:
932
        cmp     eax, XFS_DINODE_FMT_EXTENTS
936
        cmp     eax, XFS_DINODE_FMT_EXTENTS
933
        movi    eax, ERROR_FS_FAIL
937
        movi    eax, ERROR_FS_FAIL
934
        jnz     .error
938
        jnz     .error
935
        call    xfs._.get_last_dirblock
939
        call    xfs._.get_last_dirblock
936
        test    eax, eax
940
        test    eax, eax
937
        jnz     @f
941
        jnz     @f
938
        add     ebx, [ebp+XFS.inode_core_size]
942
        add     ebx, [ebp+XFS.inode_core_size]
939
        stdcall xfs._.readdir_block, ebx, [_dst]
943
        stdcall xfs._.readdir_block, ebx, [_dst]
940
        jmp     .quit
944
        jmp     .quit
941
@@:
945
@@:
942
        stdcall xfs._.readdir_leaf_node, ebx, [_dst]
946
        stdcall xfs._.readdir_leaf_node, ebx, [_dst]
943
        jmp     .quit
947
        jmp     .quit
944
.quit:
948
.quit:
945
        mov     edx, [_dst]
949
        mov     edx, [_dst]
946
        mov     ebx, [ebp+XFS.entries_read]
950
        mov     ebx, [ebp+XFS.entries_read]
947
        mov     [edx+bdfe_hdr.read_cnt], ebx
951
        mov     [edx+bdfe_hdr.read_cnt], ebx
948
        xor     eax, eax
952
        xor     eax, eax
949
.error:
953
.error:
950
        ret
954
        ret
951
endp
955
endp
952
 
956
 
953
 
957
 
954
; returns edx:eax inode or 0
958
; returns edx:eax inode or 0
955
proc xfs._.lookup_sf _name, _len
959
proc xfs._.lookup_sf _name, _len
956
        add     ebx, [ebp+XFS.inode_core_size]
960
        add     ebx, [ebp+XFS.inode_core_size]
957
        mov     esi, [_name]
961
        mov     esi, [_name]
958
        mov     ecx, [_len]
962
        mov     ecx, [_len]
959
        cmp     ecx, 2
963
        cmp     ecx, 2
960
        ja      .common
964
        ja      .common
961
        jz      .check_parent
965
        jz      .check_parent
962
.check_self:
966
.check_self:
963
        cmp     byte[esi], '.'
967
        cmp     byte[esi], '.'
964
        jnz     .common
968
        jnz     .common
965
        mov     eax, [ebp+XFS.inode_self.lo]
969
        mov     eax, [ebp+XFS.inode_self.lo]
966
        mov     edx, [ebp+XFS.inode_self.hi]
970
        mov     edx, [ebp+XFS.inode_self.hi]
967
        jmp     .quit
971
        jmp     .quit
968
.check_parent:
972
.check_parent:
969
        cmp     word[esi], '..'
973
        cmp     word[esi], '..'
970
        jnz     .common
974
        jnz     .common
971
        lea     edx, [ebx+xfs_dir2_sf.hdr.parent]
975
        lea     edx, [ebx+xfs_dir2_sf.hdr.parent]
972
        call    xfs._.get_inode_number_sf
976
        call    xfs._.get_inode_number_sf
973
        jmp     .quit
977
        jmp     .quit
974
.common:
978
.common:
975
        movzx   edx, [ebx+xfs_dir2_sf.hdr.count]
979
        movzx   edx, [ebx+xfs_dir2_sf.hdr.count]
976
        movi    eax, 0
980
        movi    eax, 0
977
        cmp     [ebx+xfs_dir2_sf.hdr.i8count], 0
981
        cmp     [ebx+xfs_dir2_sf.hdr.i8count], 0
978
        setnz   al
982
        setnz   al
979
        lea     eax, [eax*4+4]
983
        lea     eax, [eax*4+4]
980
        lea     edi, [ebx+xfs_dir2_sf.hdr.parent+eax]
984
        lea     edi, [ebx+xfs_dir2_sf.hdr.parent+eax]
981
.next_name:
985
.next_name:
982
        dec     edx
986
        dec     edx
983
        jns     @f
987
        jns     @f
984
        movi    eax, ERROR_FILE_NOT_FOUND
988
        movi    eax, ERROR_FILE_NOT_FOUND
985
        jmp     .error
989
        jmp     .error
986
@@:
990
@@:
987
        movzx   ecx, [edi+xfs_dir2_sf_entry.namelen]
991
        movzx   ecx, [edi+xfs_dir2_sf_entry.namelen]
988
        add     edi, xfs_dir2_sf_entry.name
992
        add     edi, xfs_dir2_sf_entry.name
989
        mov     esi, [_name]
993
        mov     esi, [_name]
990
        cmp     ecx, [_len]
994
        cmp     ecx, [_len]
991
        jnz     @f
995
        jnz     @f
992
        repz cmpsb
996
        repz cmpsb
993
        jz      .found
997
        jz      .found
994
@@:
998
@@:
995
        add     edi, [ebp+XFS.ftype_size]
999
        add     edi, [ebp+XFS.ftype_size]
996
        add     edi, ecx
1000
        add     edi, ecx
997
        add     edi, eax
1001
        add     edi, eax
998
        jmp     .next_name
1002
        jmp     .next_name
999
.found:
1003
.found:
1000
        add     edi, [ebp+XFS.ftype_size]
1004
        add     edi, [ebp+XFS.ftype_size]
1001
        mov     edx, edi
1005
        mov     edx, edi
1002
        call    xfs._.get_inode_number_sf
1006
        call    xfs._.get_inode_number_sf
1003
.quit:
1007
.quit:
1004
        cmp     esp, esp
1008
        cmp     esp, esp
1005
.error:
1009
.error:
1006
        ret
1010
        ret
1007
endp
1011
endp
1008
 
1012
 
1009
 
1013
 
1010
proc xfs._.lookup_block uses esi, _name, _len
1014
proc xfs._.lookup_block uses esi, _name, _len
1011
        add     ebx, [ebp+XFS.inode_core_size]
1015
        add     ebx, [ebp+XFS.inode_core_size]
1012
        mov     eax, ebx
1016
        mov     eax, ebx
1013
        mov     ebx, [ebp+XFS.cur_dirblock]
1017
        mov     ebx, [ebp+XFS.cur_dirblock]
1014
        stdcall xfs._.extent_unpack, eax
1018
        stdcall xfs._.extent_unpack, eax
1015
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], ebx
1019
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], \
-
 
1020
                [ebp+XFS.extent.br_startblock.hi], ebx
1016
        jnz     .error
1021
        jnz     .error
1017
        mov     eax, [ebp+XFS.dir_block_magic]
1022
        mov     eax, [ebp+XFS.dir_block_magic]
1018
        cmp     [ebx+xfs_dir2_block.hdr.magic], eax
1023
        cmp     [ebx+xfs_dir2_block.hdr.magic], eax
1019
        movi    eax, ERROR_FS_FAIL
1024
        movi    eax, ERROR_FS_FAIL
1020
        jnz     .error
1025
        jnz     .error
1021
        stdcall xfs_hashname, [_name+4], [_len]
1026
        stdcall xfs_hashname, [_name+4], [_len]
1022
        add     ebx, [ebp+XFS.dirblocksize]
1027
        add     ebx, [ebp+XFS.dirblocksize]
1023
        movbe   ecx, [ebx-sizeof.xfs_dir2_block_tail+xfs_dir2_block_tail.count]
1028
        movbe   ecx, [ebx-sizeof.xfs_dir2_block_tail+xfs_dir2_block_tail.count]
1024
        lea     edx, [ecx*sizeof.xfs_dir2_leaf_entry+sizeof.xfs_dir2_block_tail]
1029
        lea     edx, [ecx*sizeof.xfs_dir2_leaf_entry+sizeof.xfs_dir2_block_tail]
1025
        sub     ebx, edx
1030
        sub     ebx, edx
1026
        stdcall xfs._.get_addr_by_hash, ebx, ecx
1031
        stdcall xfs._.get_addr_by_hash, ebx, ecx
1027
        jnz     .error
1032
        jnz     .error
1028
        mov     ebx, [ebp+XFS.cur_dirblock]
1033
        mov     ebx, [ebp+XFS.cur_dirblock]
1029
        movbe   edx, [ebx+eax*XFS_DIR2_DATA_ALIGN+xfs_dir2_data_entry.inumber.lo]
1034
        movbe   edx, [ebx+eax*XFS_DIR2_DATA_ALIGN+xfs_dir2_data_entry.inumber.lo]
1030
        movbe   eax, [ebx+eax*XFS_DIR2_DATA_ALIGN+xfs_dir2_data_entry.inumber.hi]
1035
        movbe   eax, [ebx+eax*XFS_DIR2_DATA_ALIGN+xfs_dir2_data_entry.inumber.hi]
1031
.quit:
1036
.quit:
1032
.error:
1037
.error:
1033
        ret
1038
        ret
1034
endp
1039
endp
1035
 
1040
 
1036
 
1041
 
1037
proc xfs._.get_inode_by_addr uses ebx esi edi, _inode_buf
1042
proc xfs._.get_inode_by_addr uses ebx esi edi, _inode_buf
1038
        xor     edx, edx
1043
        xor     edx, edx
1039
        shld    edx, eax, XFS_DIR2_DATA_ALIGN_LOG
1044
        shld    edx, eax, XFS_DIR2_DATA_ALIGN_LOG
1040
        shl     eax, XFS_DIR2_DATA_ALIGN_LOG
1045
        shl     eax, XFS_DIR2_DATA_ALIGN_LOG
1041
        mov     esi, [ebp+XFS.dirblocksize]
1046
        mov     esi, [ebp+XFS.dirblocksize]
1042
        dec     esi
1047
        dec     esi
1043
        and     esi, eax
1048
        and     esi, eax
1044
        mov     ecx, [ebp+XFS.blocklog]
1049
        mov     ecx, [ebp+XFS.blocklog]
1045
        add     ecx, [ebp+XFS.dirblklog]
1050
        add     ecx, [ebp+XFS.dirblklog]
1046
        shrd    eax, edx, cl
1051
        shrd    eax, edx, cl
1047
        shr     edx, cl
1052
        shr     edx, cl
1048
        mov     ecx, [ebp+XFS.dirblklog]
1053
        mov     ecx, [ebp+XFS.dirblklog]
1049
        shld    edx, eax, cl
1054
        shld    edx, eax, cl
1050
        shl     eax, cl
1055
        shl     eax, cl
1051
        mov     ebx, [_inode_buf]
1056
        mov     ebx, [_inode_buf]
1052
        cmp     [ebx+xfs_inode.di_core.di_format], XFS_DINODE_FMT_EXTENTS
1057
        cmp     [ebx+xfs_inode.di_core.di_format], XFS_DINODE_FMT_EXTENTS
1053
        jz      .extents
1058
        jz      .extents
1054
        cmp     [ebx+xfs_inode.di_core.di_format], XFS_DINODE_FMT_BTREE
1059
        cmp     [ebx+xfs_inode.di_core.di_format], XFS_DINODE_FMT_BTREE
1055
        jz      .btree
1060
        jz      .btree
1056
        jmp     .error
1061
        jmp     .error
1057
.extents:
1062
.extents:
1058
        mov     ecx, [ebp+XFS.nextents_offset]
1063
        mov     ecx, [ebp+XFS.nextents_offset]
1059
        movbe   ecx, [ebx+ecx]
1064
        movbe   ecx, [ebx+ecx]
1060
        add     ebx, [ebp+XFS.inode_core_size]
1065
        add     ebx, [ebp+XFS.inode_core_size]
1061
        mov     [ebp+XFS.offset_begin.lo], eax
1066
        mov     [ebp+XFS.offset_begin.lo], eax
1062
        mov     [ebp+XFS.offset_begin.hi], edx
1067
        mov     [ebp+XFS.offset_begin.hi], edx
1063
        stdcall xfs._.extent_list.seek, ecx
1068
        stdcall xfs._.extent_list.seek, ecx
1064
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], [ebp+XFS.cur_dirblock]
1069
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], [ebp+XFS.cur_dirblock]
1065
        jnz     .error
1070
        jnz     .error
1066
        jmp     .common
1071
        jmp     .common
1067
.btree:
1072
.btree:
1068
        movzx   ecx, [ebx+xfs_inode.di_core.di_forkoff]
1073
        movzx   ecx, [ebx+xfs_inode.di_core.di_forkoff]
1069
        shl     ecx, 3
1074
        shl     ecx, 3
1070
        test    ecx, ecx
1075
        test    ecx, ecx
1071
        jnz     @f
1076
        jnz     @f
1072
        mov     ecx, [ebp+XFS.inodesize]
1077
        mov     ecx, [ebp+XFS.inodesize]
1073
        sub     ecx, [ebp+XFS.inode_core_size]
1078
        sub     ecx, [ebp+XFS.inode_core_size]
1074
@@:
1079
@@:
1075
        add     ebx, [ebp+XFS.inode_core_size]
1080
        add     ebx, [ebp+XFS.inode_core_size]
1076
        stdcall xfs._.btree_read_block, ebx, ecx, eax, edx, [ebp+XFS.cur_dirblock]
1081
        stdcall xfs._.btree_read_block, ebx, ecx, eax, edx, [ebp+XFS.cur_dirblock]
1077
.common:
1082
.common:
1078
        mov     ebx, [ebp+XFS.cur_dirblock]
1083
        mov     ebx, [ebp+XFS.cur_dirblock]
1079
        mov     eax, [ebp+XFS.dir_data_magic]
1084
        mov     eax, [ebp+XFS.dir_data_magic]
1080
        cmp     [ebx+xfs_dir2_block.hdr.magic], eax
1085
        cmp     [ebx+xfs_dir2_block.hdr.magic], eax
1081
        movi    eax, ERROR_FS_FAIL
1086
        movi    eax, ERROR_FS_FAIL
1082
        jnz     .error
1087
        jnz     .error
1083
        movbe   edx, [ebx+esi+xfs_dir2_data_entry.inumber.lo]
1088
        movbe   edx, [ebx+esi+xfs_dir2_data_entry.inumber.lo]
1084
        movbe   eax, [ebx+esi+xfs_dir2_data_entry.inumber.hi]
1089
        movbe   eax, [ebx+esi+xfs_dir2_data_entry.inumber.hi]
1085
.error:
1090
.error:
1086
.quit:
1091
.quit:
1087
        ret
1092
        ret
1088
endp
1093
endp
1089
 
1094
 
1090
 
1095
 
1091
proc xfs._.lookup_leaf uses ebx esi edi, _name, _len
1096
proc xfs._.lookup_leaf uses ebx esi edi, _name, _len
1092
        mov     ecx, [ebp+XFS.nextents_offset]
1097
        mov     ecx, [ebp+XFS.nextents_offset]
1093
        movbe   ecx, [ebx+ecx]
1098
        movbe   ecx, [ebx+ecx]
1094
        add     ebx, [ebp+XFS.inode_core_size]
1099
        add     ebx, [ebp+XFS.inode_core_size]
1095
        mov     eax, [ebp+XFS.dir2_leaf_offset_blocks.lo]
1100
        mov     eax, [ebp+XFS.dir2_leaf_offset_blocks.lo]
1096
        mov     [ebp+XFS.offset_begin.lo], ecx
1101
        mov     [ebp+XFS.offset_begin.lo], ecx
1097
        mov     eax, [ebp+XFS.dir2_leaf_offset_blocks.hi]
1102
        mov     eax, [ebp+XFS.dir2_leaf_offset_blocks.hi]
1098
        mov     [ebp+XFS.offset_begin.hi], ecx
1103
        mov     [ebp+XFS.offset_begin.hi], ecx
1099
        stdcall xfs._.extent_list.seek, ecx
1104
        stdcall xfs._.extent_list.seek, ecx
1100
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], [ebp+XFS.cur_dirblock]
1105
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], \
-
 
1106
                [ebp+XFS.extent.br_startblock.hi], [ebp+XFS.cur_dirblock]
1101
        jnz     .error
1107
        jnz     .error
1102
        mov     ebx, [ebp+XFS.cur_dirblock]
1108
        mov     ebx, [ebp+XFS.cur_dirblock]
1103
        movzx   eax, [ebp+XFS.dir_leaf1_magic]
1109
        movzx   eax, [ebp+XFS.dir_leaf1_magic]
1104
        cmp     [ebx+xfs_dir2_leaf.hdr.info.magic], ax
1110
        cmp     [ebx+xfs_dir2_leaf.hdr.info.magic], ax
1105
        movi    eax, ERROR_FS_FAIL
1111
        movi    eax, ERROR_FS_FAIL
1106
        jnz     .error
1112
        jnz     .error
1107
        stdcall xfs_hashname, [_name+4], [_len]
1113
        stdcall xfs_hashname, [_name+4], [_len]
1108
        cmp     [ebp+XFS.version], 5
1114
        cmp     [ebp+XFS.version], 5
1109
        jz      .v5
1115
        jz      .v5
1110
.v4:
1116
.v4:
1111
        movzx   ecx, [ebx+xfs_dir2_leaf.hdr.count]
1117
        movzx   ecx, [ebx+xfs_dir2_leaf.hdr.count]
1112
        xchg    cl, ch
1118
        xchg    cl, ch
1113
        add     ebx, xfs_dir2_leaf.ents
1119
        add     ebx, xfs_dir2_leaf.ents
1114
        jmp     .vcommon
1120
        jmp     .vcommon
1115
.v5:
1121
.v5:
1116
        movzx   ecx, [ebx+xfs_dir3_leaf.hdr.count]
1122
        movzx   ecx, [ebx+xfs_dir3_leaf.hdr.count]
1117
        xchg    cl, ch
1123
        xchg    cl, ch
1118
        add     ebx, xfs_dir3_leaf.ents
1124
        add     ebx, xfs_dir3_leaf.ents
1119
.vcommon:
1125
.vcommon:
1120
        stdcall xfs._.get_addr_by_hash, ebx, ecx
1126
        stdcall xfs._.get_addr_by_hash, ebx, ecx
1121
        jnz     .error
1127
        jnz     .error
1122
        stdcall xfs._.get_inode_by_addr, [ebp+XFS.cur_inode_save]
1128
        stdcall xfs._.get_inode_by_addr, [ebp+XFS.cur_inode_save]
1123
.quit:
1129
.quit:
1124
.error:
1130
.error:
1125
        ret
1131
        ret
1126
endp
1132
endp
1127
 
1133
 
1128
 
1134
 
1129
proc xfs._.lookup_node uses ebx esi edi, _name, _len
1135
proc xfs._.lookup_node uses ebx esi edi, _name, _len
1130
locals
1136
locals
1131
        .hash dd ?
1137
        .hash dd ?
1132
endl
1138
endl
1133
        mov     [ebp+XFS.cur_inode_save], ebx
1139
        mov     [ebp+XFS.cur_inode_save], ebx
1134
        stdcall xfs_hashname, [_name+4], [_len]
1140
        stdcall xfs_hashname, [_name+4], [_len]
1135
        mov     [.hash], eax
1141
        mov     [.hash], eax
1136
        mov     edx, [ebp+XFS.nextents_offset]
1142
        mov     edx, [ebp+XFS.nextents_offset]
1137
        movbe   edx, [ebx+edx]
1143
        movbe   edx, [ebx+edx]
1138
        mov     esi, [ebp+XFS.dir2_leaf_offset_blocks.lo]
1144
        mov     esi, [ebp+XFS.dir2_leaf_offset_blocks.lo]
1139
.begin:
1145
.begin:
1140
        mov     ebx, [ebp+XFS.cur_inode_save]
1146
        mov     ebx, [ebp+XFS.cur_inode_save]
1141
        mov     eax, ebx
1147
        mov     eax, ebx
1142
        add     eax, [ebp+XFS.inode_core_size]
1148
        add     eax, [ebp+XFS.inode_core_size]
1143
        mov     edx, [ebp+XFS.nextents_offset]
1149
        mov     edx, [ebp+XFS.nextents_offset]
1144
        movbe   edx, [ebx+edx]
1150
        movbe   edx, [ebx+edx]
1145
        mov     ebx, eax
1151
        mov     ebx, eax
1146
        mov     [ebp+XFS.offset_begin.lo], esi
1152
        mov     [ebp+XFS.offset_begin.lo], esi
1147
        mov     [ebp+XFS.offset_begin.hi], 0
1153
        mov     [ebp+XFS.offset_begin.hi], 0
1148
        stdcall xfs._.extent_list.seek, edx
1154
        stdcall xfs._.extent_list.seek, edx
1149
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], [ebp+XFS.cur_dirblock]
1155
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], [ebp+XFS.cur_dirblock]
1150
        jnz     .error
1156
        jnz     .error
1151
        mov     ebx, [ebp+XFS.cur_dirblock]
1157
        mov     ebx, [ebp+XFS.cur_dirblock]
1152
        movzx   eax, [ebp+XFS.da_node_magic]
1158
        movzx   eax, [ebp+XFS.da_node_magic]
1153
        cmp     [ebx+xfs_da_intnode.hdr.info.magic], ax
1159
        cmp     [ebx+xfs_da_intnode.hdr.info.magic], ax
1154
        jz      .node
1160
        jz      .node
1155
        movzx   eax, [ebp+XFS.dir_leafn_magic]
1161
        movzx   eax, [ebp+XFS.dir_leafn_magic]
1156
        cmp     [ebx+xfs_dir2_leaf.hdr.info.magic], ax
1162
        cmp     [ebx+xfs_dir2_leaf.hdr.info.magic], ax
1157
        jz      .leaf
1163
        jz      .leaf
1158
        movi    eax, ERROR_FS_FAIL
1164
        movi    eax, ERROR_FS_FAIL
1159
        jmp     .error
1165
        jmp     .error
1160
.node:
1166
.node:
1161
        cmp     [ebp+XFS.version], 5
1167
        cmp     [ebp+XFS.version], 5
1162
        jz      .node.v5
1168
        jz      .node.v5
1163
.node.v4:
1169
.node.v4:
1164
        lea     eax, [ebx+sizeof.xfs_da_intnode]
1170
        lea     eax, [ebx+sizeof.xfs_da_intnode]
1165
        movzx   edx, [ebx+xfs_da_intnode.hdr.count]
1171
        movzx   edx, [ebx+xfs_da_intnode.hdr.count]
1166
        jmp     .node.vcommon
1172
        jmp     .node.vcommon
1167
.node.v5:
1173
.node.v5:
1168
        lea     eax, [ebx+sizeof.xfs_da3_intnode]
1174
        lea     eax, [ebx+sizeof.xfs_da3_intnode]
1169
        movzx   edx, [ebx+xfs_da3_intnode.hdr.count]
1175
        movzx   edx, [ebx+xfs_da3_intnode.hdr.count]
1170
.node.vcommon:
1176
.node.vcommon:
1171
        xchg    dl, dh
1177
        xchg    dl, dh
1172
        stdcall xfs._.get_before_by_hashval, eax, edx, [.hash]
1178
        stdcall xfs._.get_before_by_hashval, eax, edx, [.hash]
1173
        jnz     .error
1179
        jnz     .error
1174
        mov     esi, eax
1180
        mov     esi, eax
1175
        jmp     .begin
1181
        jmp     .begin
1176
.leaf:
1182
.leaf:
1177
        cmp     [ebp+XFS.version], 5
1183
        cmp     [ebp+XFS.version], 5
1178
        jz      .leaf.v5
1184
        jz      .leaf.v5
1179
.leaf.v4:
1185
.leaf.v4:
1180
        movzx   ecx, [ebx+xfs_dir2_leaf.hdr.count]
1186
        movzx   ecx, [ebx+xfs_dir2_leaf.hdr.count]
1181
        xchg    cl, ch
1187
        xchg    cl, ch
1182
        add     ebx, xfs_dir2_leaf.ents
1188
        add     ebx, xfs_dir2_leaf.ents
1183
        jmp     .leaf.vcommon
1189
        jmp     .leaf.vcommon
1184
.leaf.v5:
1190
.leaf.v5:
1185
        movzx   ecx, [ebx+xfs_dir3_leaf.hdr.count]
1191
        movzx   ecx, [ebx+xfs_dir3_leaf.hdr.count]
1186
        xchg    cl, ch
1192
        xchg    cl, ch
1187
        add     ebx, xfs_dir3_leaf.ents
1193
        add     ebx, xfs_dir3_leaf.ents
1188
.leaf.vcommon:
1194
.leaf.vcommon:
1189
        mov     eax, [.hash]
1195
        mov     eax, [.hash]
1190
        stdcall xfs._.get_addr_by_hash, ebx, ecx
1196
        stdcall xfs._.get_addr_by_hash, ebx, ecx
1191
        jnz     .error
1197
        jnz     .error
1192
        stdcall xfs._.get_inode_by_addr, [ebp+XFS.cur_inode_save]
1198
        stdcall xfs._.get_inode_by_addr, [ebp+XFS.cur_inode_save]
1193
.quit:
1199
.quit:
1194
        cmp     esp, esp
1200
        cmp     esp, esp
1195
        ret
1201
        ret
1196
.error:
1202
.error:
1197
        test    esp, esp
1203
        test    esp, esp
1198
        ret
1204
        ret
1199
endp
1205
endp
1200
 
1206
 
1201
 
1207
 
1202
proc xfs._.lookup_btree uses ebx esi edi, _name, _len
1208
proc xfs._.lookup_btree uses ebx esi edi, _name, _len
1203
locals
1209
locals
1204
        .hash dd ?
1210
        .hash dd ?
1205
endl
1211
endl
1206
        mov     [ebp+XFS.cur_inode_save], ebx
1212
        mov     [ebp+XFS.cur_inode_save], ebx
1207
        stdcall xfs_hashname, [_name+4], [_len]
1213
        stdcall xfs_hashname, [_name+4], [_len]
1208
        mov     [.hash], eax
1214
        mov     [.hash], eax
1209
        mov     edx, [ebp+XFS.dir2_leaf_offset_blocks.hi]
1215
        mov     edx, [ebp+XFS.dir2_leaf_offset_blocks.hi]
1210
        mov     eax, [ebp+XFS.dir2_leaf_offset_blocks.lo]
1216
        mov     eax, [ebp+XFS.dir2_leaf_offset_blocks.lo]
1211
        jmp     .next_level.first
1217
        jmp     .next_level.first
1212
.next_level:
1218
.next_level:
1213
        lea     eax, [ebx+sizeof.xfs_da_intnode]
1219
        lea     eax, [ebx+sizeof.xfs_da_intnode]
1214
        movzx   edx, [ebx+xfs_da_intnode.hdr.count]
1220
        movzx   edx, [ebx+xfs_da_intnode.hdr.count]
1215
        xchg    dl, dh
1221
        xchg    dl, dh
1216
        stdcall xfs._.get_before_by_hashval, eax, edx, [.hash]
1222
        stdcall xfs._.get_before_by_hashval, eax, edx, [.hash]
1217
        jnz     .error
1223
        jnz     .error
1218
        xor     edx, edx
1224
        xor     edx, edx
1219
.next_level.first:
1225
.next_level.first:
1220
        mov     ebx, [ebp+XFS.cur_inode_save]
1226
        mov     ebx, [ebp+XFS.cur_inode_save]
1221
        movzx   ecx, [ebx+xfs_inode.di_core.di_forkoff]
1227
        movzx   ecx, [ebx+xfs_inode.di_core.di_forkoff]
1222
        shl     ecx, 3
1228
        shl     ecx, 3
1223
        test    ecx, ecx
1229
        test    ecx, ecx
1224
        jnz     @f
1230
        jnz     @f
1225
        mov     ecx, [ebp+XFS.inodesize]
1231
        mov     ecx, [ebp+XFS.inodesize]
1226
        sub     ecx, [ebp+XFS.inode_core_size]
1232
        sub     ecx, [ebp+XFS.inode_core_size]
1227
@@:
1233
@@:
1228
        add     ebx, [ebp+XFS.inode_core_size]
1234
        add     ebx, [ebp+XFS.inode_core_size]
1229
        stdcall xfs._.btree_read_block, ebx, ecx, eax, edx, [ebp+XFS.cur_dirblock]
1235
        stdcall xfs._.btree_read_block, ebx, ecx, eax, edx, [ebp+XFS.cur_dirblock]
1230
        mov     ebx, [ebp+XFS.cur_dirblock]
1236
        mov     ebx, [ebp+XFS.cur_dirblock]
-
 
1237
        movzx   eax, [ebp+XFS.da_node_magic]
1231
        cmp     [ebx+xfs_da_intnode.hdr.info.magic], XFS_DA_NODE_MAGIC
1238
        cmp     [ebx+xfs_da_blkinfo.magic], ax
1232
        jz      .next_level
1239
        jz      .next_level
-
 
1240
        movzx   eax, [ebp+XFS.dir_leafn_magic]
1233
        cmp     [ebx+xfs_dir2_leaf.hdr.info.magic], XFS_DIR2_LEAFN_MAGIC
1241
        cmp     [ebx+xfs_da_blkinfo.magic], ax
1234
        jz      .leafn
1242
        jz      .leafn
-
 
1243
        movzx   eax, [ebp+XFS.dir_leaf1_magic]
1235
        cmp     [ebx+xfs_dir2_leaf.hdr.info.magic], XFS_DIR2_LEAF1_MAGIC
1244
        cmp     [ebx+xfs_da_blkinfo.magic], ax
1236
        jnz     .error
1245
        jnz     .error
1237
        mov     eax, [.hash]
1246
        mov     eax, [.hash]
1238
        movzx   ecx, [ebx+xfs_dir2_leaf.hdr.count]
1247
        mov     ecx, [ebp+XFS.dirx_leaf_hdr_count_offset]
-
 
1248
        movzx   ecx, word[ebx+ecx]
1239
        xchg    cl, ch
1249
        xchg    cl, ch
1240
        add     ebx, xfs_dir2_leaf.ents
1250
        add     ebx, [ebp+XFS.dirx_leaf_ents_offset]
1241
        stdcall xfs._.get_addr_by_hash, ebx, ecx
1251
        stdcall xfs._.get_addr_by_hash, ebx, ecx
1242
        jnz     .error
1252
        jnz     .error
1243
        mov     ebx, [ebp+XFS.cur_dirblock]
1253
        mov     ebx, [ebp+XFS.cur_dirblock]
1244
        jmp     .got_addr
1254
        jmp     .got_addr
1245
.leafn:
1255
.leafn:
1246
        movzx   ecx, [ebx+xfs_dir2_leaf.hdr.count]
1256
        mov     ecx, [ebp+XFS.dirx_leaf_hdr_count_offset]
-
 
1257
        movzx   ecx, word[ebx+ecx]
1247
        xchg    cl, ch
1258
        xchg    cl, ch
1248
        add     ebx, xfs_dir2_leaf.ents
1259
        add     ebx, [ebp+XFS.dirx_leaf_ents_offset]
1249
        mov     eax, [.hash]
1260
        mov     eax, [.hash]
1250
        stdcall xfs._.get_addr_by_hash, ebx, ecx
1261
        stdcall xfs._.get_addr_by_hash, ebx, ecx
1251
        jnz     .error
1262
        jnz     .error
1252
        mov     ebx, [ebp+XFS.cur_block]
1263
        mov     ebx, [ebp+XFS.cur_block]
1253
.got_addr:
1264
.got_addr:
1254
        stdcall xfs._.get_inode_by_addr, [ebp+XFS.cur_inode_save]
1265
        stdcall xfs._.get_inode_by_addr, [ebp+XFS.cur_inode_save]
1255
.quit:
1266
.quit:
1256
        cmp     esp, esp
1267
        cmp     esp, esp
1257
        ret
1268
        ret
1258
.error:
1269
.error:
1259
        test    esp, esp
1270
        test    esp, esp
1260
        ret
1271
        ret
1261
endp
1272
endp
1262
 
1273
 
1263
 
1274
 
1264
; search for the _name in _inode dir
1275
; search for the _name in _inode dir
1265
; called for each /path/component/to/my/file
1276
; called for each /path/component/to/my/file
1266
; out:
1277
; out:
1267
; ZF/zf   = ok/fail
1278
; ZF/zf   = ok/fail
1268
; edx:eax = inode/garbage:error
1279
; edx:eax = inode/garbage:error
1269
proc xfs._.get_inode_short uses esi, _inode:qword, _len, _name
1280
proc xfs._.get_inode_short uses esi, _inode:qword, _len, _name
1270
        mov     esi, [_name]
1281
        mov     esi, [_name]
1271
        mov     eax, dword[_inode+DQ.lo]
1282
        mov     eax, dword[_inode+DQ.lo]
1272
        mov     edx, dword[_inode+DQ.hi]
1283
        mov     edx, dword[_inode+DQ.hi]
1273
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.cur_inode]
1284
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.cur_inode]
1274
        test    eax, eax
1285
        test    eax, eax
1275
        movi    eax, ERROR_FS_FAIL
1286
        movi    eax, ERROR_FS_FAIL
1276
        jnz     .error
1287
        jnz     .error
1277
        ; switch directory ondisk format
1288
        ; switch directory ondisk format
1278
        mov     ebx, edx
1289
        mov     ebx, edx
1279
        mov     [ebp+XFS.cur_inode_save], ebx
1290
        mov     [ebp+XFS.cur_inode_save], ebx
1280
        movzx   eax, [ebx+xfs_inode.di_core.di_format]
1291
        movzx   eax, [ebx+xfs_inode.di_core.di_format]
1281
        cmp     eax, XFS_DINODE_FMT_LOCAL
1292
        cmp     eax, XFS_DINODE_FMT_LOCAL
1282
        mov     edi, xfs._.lookup_sf
1293
        mov     edi, xfs._.lookup_sf
1283
        jz      .lookup
1294
        jz      .lookup
1284
        cmp     eax, XFS_DINODE_FMT_BTREE
1295
        cmp     eax, XFS_DINODE_FMT_BTREE
1285
        mov     edi, xfs._.lookup_btree
1296
        mov     edi, xfs._.lookup_btree
1286
        jz      .lookup
1297
        jz      .lookup
1287
        cmp     eax, XFS_DINODE_FMT_EXTENTS
1298
        cmp     eax, XFS_DINODE_FMT_EXTENTS
1288
        jnz     .error
1299
        jnz     .error
1289
        call    xfs._.get_last_dirblock
1300
        call    xfs._.get_last_dirblock
1290
        test    eax, eax
1301
        test    eax, eax
1291
        mov     edi, xfs._.lookup_block
1302
        mov     edi, xfs._.lookup_block
1292
        jz      .lookup
1303
        jz      .lookup
1293
        cmp     edx, [ebp+XFS.dir2_free_offset_blocks.hi]
1304
        cmp     edx, [ebp+XFS.dir2_free_offset_blocks.hi]
1294
        mov     edi, xfs._.lookup_node
1305
        mov     edi, xfs._.lookup_node
1295
        ja      .lookup
1306
        ja      .lookup
1296
        cmp     eax, [ebp+XFS.dir2_free_offset_blocks.lo]
1307
        cmp     eax, [ebp+XFS.dir2_free_offset_blocks.lo]
1297
        jae     .lookup
1308
        jae     .lookup
1298
        mov     edi, xfs._.lookup_leaf
1309
        mov     edi, xfs._.lookup_leaf
1299
.lookup:
1310
.lookup:
1300
        stdcall edi, [_name+4], [_len]
1311
        stdcall edi, [_name+4], [_len]
1301
.error:
1312
.error:
1302
        ret
1313
        ret
1303
endp
1314
endp
1304
 
1315
 
1305
 
1316
 
1306
; ZF/zf   = ok/fail
1317
; ZF/zf   = ok/fail
1307
; edx:eax = inode/garbage:error
1318
; edx:eax = inode/garbage:error
1308
proc xfs_get_inode uses ebx esi edi, _name
1319
proc xfs_get_inode uses ebx esi edi, _name
1309
        ; call *._.get_inode_short until file is found / error returned
1320
        ; call *._.get_inode_short until file is found / error returned
1310
        ; start from the root inode
1321
        ; start from the root inode
1311
        mov     eax, [ebp+XFS.rootino.lo]
1322
        mov     eax, [ebp+XFS.rootino.lo]
1312
        mov     edx, [ebp+XFS.rootino.hi]
1323
        mov     edx, [ebp+XFS.rootino.hi]
1313
        mov     esi, [_name]
1324
        mov     esi, [_name]
1314
.next_dir:
1325
.next_dir:
1315
@@:
1326
@@:
1316
        cmp     byte[esi], '/'
1327
        cmp     byte[esi], '/'
1317
        jnz     @f
1328
        jnz     @f
1318
        inc     esi
1329
        inc     esi
1319
        jmp     @b
1330
        jmp     @b
1320
@@:
1331
@@:
1321
        cmp     byte[esi], 0
1332
        cmp     byte[esi], 0
1322
        jz      .found
1333
        jz      .found
1323
        push    esi
1334
        push    esi
1324
        inc     esi
1335
        inc     esi
1325
@@:
1336
@@:
1326
        cmp     byte[esi], 0
1337
        cmp     byte[esi], 0
1327
        jz      @f
1338
        jz      @f
1328
        cmp     byte[esi], '/'
1339
        cmp     byte[esi], '/'
1329
        jz      @f
1340
        jz      @f
1330
        inc     esi
1341
        inc     esi
1331
        jmp     @b
1342
        jmp     @b
1332
@@:
1343
@@:
1333
        mov     ecx, esi
1344
        mov     ecx, esi
1334
        sub     ecx, [esp]
1345
        sub     ecx, [esp]
1335
        mov     [ebp+XFS.inode_self.lo], eax
1346
        mov     [ebp+XFS.inode_self.lo], eax
1336
        mov     [ebp+XFS.inode_self.hi], edx
1347
        mov     [ebp+XFS.inode_self.hi], edx
1337
        stdcall xfs._.get_inode_short, eax, edx, ecx      ; esi pushed above
1348
        stdcall xfs._.get_inode_short, eax, edx, ecx      ; esi pushed above
1338
        jz      .next_dir
1349
        jz      .next_dir
1339
.error:
1350
.error:
1340
.found:
1351
.found:
1341
        ret
1352
        ret
1342
endp
1353
endp
1343
 
1354
 
1344
 
1355
 
1345
; in:  ebp = pointer to XFS structure
1356
; in:  ebp = pointer to XFS structure
1346
; in:  esi
1357
; in:  esi
1347
; in:  ebx = pointer to parameters from sysfunc 70
1358
; in:  ebx = pointer to parameters from sysfunc 70
1348
; out: eax, ebx = return values for sysfunc 70
1359
; out: eax, ebx = return values for sysfunc 70
1349
; out: [edx] -- f70.1 out structure
1360
; out: [edx] -- f70.1 out structure
1350
proc xfs_ReadFolder uses esi edi
1361
proc xfs_ReadFolder uses esi edi
1351
        call    xfs._.lock
1362
        call    xfs._.lock
1352
        stdcall xfs_get_inode, esi
1363
        stdcall xfs_get_inode, esi
1353
        jnz     .error
1364
        jnz     .error
1354
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.cur_inode]
1365
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.cur_inode]
1355
        test    eax, eax
1366
        test    eax, eax
1356
        jnz     .error
1367
        jnz     .error
1357
        stdcall xfs._.readdir, [ebx+f70s1arg.start_idx], [ebx+f70s1arg.count], [ebx+f70s1arg.buf], edx, [ebx+f70s1arg.encoding]
1368
        stdcall xfs._.readdir, [ebx+f70s1arg.start_idx], [ebx+f70s1arg.count], [ebx+f70s1arg.buf], edx, [ebx+f70s1arg.encoding]
1358
        test    eax, eax
1369
        test    eax, eax
1359
        jnz     .error
1370
        jnz     .error
1360
        mov     edx, [ebx+f70s1arg.buf]
1371
        mov     edx, [ebx+f70s1arg.buf]
1361
        mov     ecx, [ebx+f70s1arg.count]
1372
        mov     ecx, [ebx+f70s1arg.count]
1362
        cmp     [edx+bdfe_hdr.read_cnt], ecx
1373
        cmp     [edx+bdfe_hdr.read_cnt], ecx
1363
        jz      .quit
1374
        jz      .quit
1364
        movi    eax, ERROR_END_OF_FILE
1375
        movi    eax, ERROR_END_OF_FILE
1365
.quit:
1376
.quit:
1366
        mov     ebx, [edx+bdfe_hdr.read_cnt]
1377
        mov     ebx, [edx+bdfe_hdr.read_cnt]
1367
 
1378
 
1368
.error:
1379
.error:
1369
        push    eax
1380
        push    eax
1370
        call    xfs._.unlock
1381
        call    xfs._.unlock
1371
        pop     eax
1382
        pop     eax
1372
        ret
1383
        ret
1373
endp
1384
endp
1374
 
1385
 
1375
 
1386
 
1376
; edx -- pointer to inode number in big endian
1387
; edx -- pointer to inode number in big endian
1377
; ZF -- must be set at exit
1388
; ZF -- must be set at exit
1378
proc xfs._.get_inode_number_sf
1389
proc xfs._.get_inode_number_sf
1379
        cmp     [ebx+xfs_dir2_sf.hdr.i8count], 0
1390
        cmp     [ebx+xfs_dir2_sf.hdr.i8count], 0
1380
        jz      .i4bytes
1391
        jz      .i4bytes
1381
.i8bytes:
1392
.i8bytes:
1382
        movbe   eax, [edx+DQ.hi]
1393
        movbe   eax, [edx+DQ.hi]
1383
        movbe   edx, [edx+DQ.lo]
1394
        movbe   edx, [edx+DQ.lo]
1384
        ret
1395
        ret
1385
.i4bytes:
1396
.i4bytes:
1386
        movbe   eax, [edx+DQ.lo]
1397
        movbe   eax, [edx+DQ.lo]
1387
        xor     edx, edx
1398
        xor     edx, edx
1388
        ret
1399
        ret
1389
endp
1400
endp
1390
 
1401
 
1391
proc xfs._.conv_time_to_kos_epoch
1402
proc xfs._.conv_time_to_kos_epoch
1392
        movbe   eax, [ecx+DQ.hi_be]
1403
        movbe   eax, [ecx+DQ.hi_be]
1393
        call    fsTime2bdfe
1404
        call    fsTime2bdfe
1394
        ret
1405
        ret
1395
endp
1406
endp
1396
 
1407
 
1397
proc xfs._.conv_bigtime_to_kos_epoch
1408
proc xfs._.conv_bigtime_to_kos_epoch
1398
NANOSEC_PER_SEC = 1_000_000_000
1409
NANOSEC_PER_SEC = 1_000_000_000
1399
BIGTIME_TO_UNIX_OFFSET = 0x80000000     ; int32 min
1410
BIGTIME_TO_UNIX_OFFSET = 0x80000000     ; int32 min
1400
UNIXTIME_TO_KOS_OFFSET = (365*31+8)*24*60*60  ; 01.01.1970--01.01.2001
1411
UNIXTIME_TO_KOS_OFFSET = (365*31+8)*24*60*60  ; 01.01.1970--01.01.2001
1401
BIGTIME_TO_KOS_OFFSET = BIGTIME_TO_UNIX_OFFSET + UNIXTIME_TO_KOS_OFFSET
1412
BIGTIME_TO_KOS_OFFSET = BIGTIME_TO_UNIX_OFFSET + UNIXTIME_TO_KOS_OFFSET
1402
BIGTIME_TO_KOS_OFFSET_NS = BIGTIME_TO_KOS_OFFSET * NANOSEC_PER_SEC
1413
BIGTIME_TO_KOS_OFFSET_NS = BIGTIME_TO_KOS_OFFSET * NANOSEC_PER_SEC
1403
        movbe   edx, [ecx+DQ.hi_be]
1414
        movbe   edx, [ecx+DQ.hi_be]
1404
        movbe   eax, [ecx+DQ.lo_be]
1415
        movbe   eax, [ecx+DQ.lo_be]
1405
        sub     eax, BIGTIME_TO_KOS_OFFSET_NS AND 0xffffffff
1416
        sub     eax, BIGTIME_TO_KOS_OFFSET_NS AND 0xffffffff
1406
        sbb     edx, BIGTIME_TO_KOS_OFFSET_NS SHR 32
1417
        sbb     edx, BIGTIME_TO_KOS_OFFSET_NS SHR 32
1407
        jnc     .after_kos_epoch_begin
1418
        jnc     .after_kos_epoch_begin
1408
        xor     eax, eax        ; set to very begin of kolibrios epoch
1419
        xor     eax, eax        ; set to very begin of kolibrios epoch
1409
        xor     edx, edx
1420
        xor     edx, edx
1410
        jmp     .time_to_bdfe
1421
        jmp     .time_to_bdfe
1411
.after_kos_epoch_begin:
1422
.after_kos_epoch_begin:
1412
        cmp     edx, NANOSEC_PER_SEC
1423
        cmp     edx, NANOSEC_PER_SEC
1413
        jb      .time_to_bdfe
1424
        jb      .time_to_bdfe
1414
        mov     edx, NANOSEC_PER_SEC - 1
1425
        mov     edx, NANOSEC_PER_SEC - 1
1415
        mov     eax, -1         ; very end of kolibrios epoch
1426
        mov     eax, -1         ; very end of kolibrios epoch
1416
.time_to_bdfe:
1427
.time_to_bdfe:
1417
        mov     ecx, NANOSEC_PER_SEC
1428
        mov     ecx, NANOSEC_PER_SEC
1418
        div     ecx
1429
        div     ecx
1419
        call    fsTime2bdfe
1430
        call    fsTime2bdfe
1420
        ret
1431
        ret
1421
endp
1432
endp
1422
 
1433
 
1423
proc xfs_get_inode_info uses ebx esi edi, _src, _dst
1434
proc xfs_get_inode_info uses ebx esi edi, _src, _dst
1424
        ; get access time and other file properties
1435
        ; get access time and other file properties
1425
        ; useful for browsing directories
1436
        ; useful for browsing directories
1426
        ; called for each dir entry
1437
        ; called for each dir entry
1427
        xor     eax, eax
1438
        xor     eax, eax
1428
        mov     esi, [_src]
1439
        mov     esi, [_src]
1429
        movzx   ecx, [esi+xfs_inode.di_core.di_mode]
1440
        movzx   ecx, [esi+xfs_inode.di_core.di_mode]
1430
        xchg    cl, ch
1441
        xchg    cl, ch
1431
        test    ecx, S_IFDIR
1442
        test    ecx, S_IFDIR
1432
        jz      @f
1443
        jz      @f
1433
        movi    eax, 0x10       ; set directory flag
1444
        movi    eax, 0x10       ; set directory flag
1434
@@:
1445
@@:
1435
        mov     edi, [_dst]
1446
        mov     edi, [_dst]
1436
        mov     [edi+bdfe.attr], eax
1447
        mov     [edi+bdfe.attr], eax
1437
        movbe   edx, [esi+xfs_inode.di_core.di_size.hi_be]
1448
        movbe   edx, [esi+xfs_inode.di_core.di_size.hi_be]
1438
        movbe   eax, [esi+xfs_inode.di_core.di_size.lo_be]
1449
        movbe   eax, [esi+xfs_inode.di_core.di_size.lo_be]
1439
        mov     [edi+bdfe.size.hi], edx
1450
        mov     [edi+bdfe.size.hi], edx
1440
        mov     [edi+bdfe.size.lo], eax
1451
        mov     [edi+bdfe.size.lo], eax
1441
 
1452
 
1442
        add     edi, bdfe.ctime
1453
        add     edi, bdfe.ctime
1443
        lea     ecx, [esi+xfs_inode.di_core.di_ctime]
1454
        lea     ecx, [esi+xfs_inode.di_core.di_ctime]
1444
        call    [ebp+XFS.conv_time_to_kos_epoch]
1455
        call    [ebp+XFS.conv_time_to_kos_epoch]
1445
        lea     ecx, [esi+xfs_inode.di_core.di_atime]
1456
        lea     ecx, [esi+xfs_inode.di_core.di_atime]
1446
        call    [ebp+XFS.conv_time_to_kos_epoch]
1457
        call    [ebp+XFS.conv_time_to_kos_epoch]
1447
        lea     ecx, [esi+xfs_inode.di_core.di_mtime]
1458
        lea     ecx, [esi+xfs_inode.di_core.di_mtime]
1448
        call    [ebp+XFS.conv_time_to_kos_epoch]
1459
        call    [ebp+XFS.conv_time_to_kos_epoch]
1449
 
1460
 
1450
        movi    eax, ERROR_SUCCESS
1461
        movi    eax, ERROR_SUCCESS
1451
        cmp     esp, esp
1462
        cmp     esp, esp
1452
        ret
1463
        ret
1453
endp
1464
endp
1454
 
1465
 
1455
 
1466
 
1456
proc xfs._.extent_unpack uses eax ebx ecx edx, _extent_data
1467
proc xfs._.extent_unpack uses eax ebx ecx edx, _extent_data
1457
        ; extents come as packed 128bit bitfields
1468
        ; extents come as packed 128bit bitfields
1458
        ; unpack them to access internal fields
1469
        ; unpack them to access internal fields
1459
        ; write result to the XFS.extent structure
1470
        ; write result to the XFS.extent structure
1460
        mov     ebx, [_extent_data]
1471
        mov     ebx, [_extent_data]
1461
 
1472
 
1462
        xor     eax, eax
1473
        xor     eax, eax
1463
        movbe   edx, [ebx+0]
1474
        movbe   edx, [ebx+0]
1464
        test    edx, 0x80000000         ; mask, see documentation
1475
        test    edx, 0x80000000         ; mask, see documentation
1465
        setnz   al
1476
        setnz   al
1466
        mov     [ebp+XFS.extent.br_state], eax
1477
        mov     [ebp+XFS.extent.br_state], eax
1467
 
1478
 
1468
        and     edx, 0x7fffffff         ; mask
1479
        and     edx, 0x7fffffff         ; mask
1469
        movbe   eax, [ebx+4]
1480
        movbe   eax, [ebx+4]
1470
        shrd    eax, edx, 9
1481
        shrd    eax, edx, 9
1471
        shr     edx, 9
1482
        shr     edx, 9
1472
        mov     [ebp+XFS.extent.br_startoff.lo], eax
1483
        mov     [ebp+XFS.extent.br_startoff.lo], eax
1473
        mov     [ebp+XFS.extent.br_startoff.hi], edx
1484
        mov     [ebp+XFS.extent.br_startoff.hi], edx
1474
 
1485
 
1475
        movbe   edx, [ebx+4]
1486
        movbe   edx, [ebx+4]
1476
        movbe   eax, [ebx+8]
1487
        movbe   eax, [ebx+8]
1477
        movbe   ecx, [ebx+12]
1488
        movbe   ecx, [ebx+12]
1478
        and     edx, 0x000001ff         ; mask
1489
        and     edx, 0x000001ff         ; mask
1479
        shrd    ecx, eax, 21
1490
        shrd    ecx, eax, 21
1480
        shrd    eax, edx, 21
1491
        shrd    eax, edx, 21
1481
        mov     [ebp+XFS.extent.br_startblock.lo], ecx
1492
        mov     [ebp+XFS.extent.br_startblock.lo], ecx
1482
        mov     [ebp+XFS.extent.br_startblock.hi], eax
1493
        mov     [ebp+XFS.extent.br_startblock.hi], eax
1483
 
1494
 
1484
        movbe   eax, [ebx+12]
1495
        movbe   eax, [ebx+12]
1485
        and     eax, 0x001fffff         ; mask
1496
        and     eax, 0x001fffff         ; mask
1486
        mov     [ebp+XFS.extent.br_blockcount], eax
1497
        mov     [ebp+XFS.extent.br_blockcount], eax
1487
        ret
1498
        ret
1488
endp
1499
endp
1489
 
1500
 
1490
 
1501
 
1491
proc xfs_hashname uses ecx esi, _name, _len
1502
proc xfs_hashname uses ecx esi, _name, _len
1492
        xor     eax, eax
1503
        xor     eax, eax
1493
        mov     esi, [_name]
1504
        mov     esi, [_name]
1494
        mov     ecx, [_len]
1505
        mov     ecx, [_len]
1495
@@:
1506
@@:
1496
        rol     eax, 7
1507
        rol     eax, 7
1497
        xor     al, [esi]
1508
        xor     al, [esi]
1498
        add     esi, 1
1509
        add     esi, 1
1499
        dec     ecx
1510
        dec     ecx
1500
        jnz     @b
1511
        jnz     @b
1501
        ret
1512
        ret
1502
endp
1513
endp
1503
 
1514
 
1504
 
1515
 
1505
; eax -- hash value
1516
; eax -- hash value
1506
proc xfs._.get_addr_by_hash uses ebx esi, _base, _len
1517
proc xfs._.get_addr_by_hash uses ebx esi, _base, _len
1507
        ; look for the directory entry offset by its file name hash
1518
        ; look for the directory entry offset by its file name hash
1508
        ; allows fast file search for block, leaf and node directories
1519
        ; allows fast file search for block, leaf and node directories
1509
        ; binary (ternary) search
1520
        ; binary (ternary) search
1510
        mov     ebx, [_base]
1521
        mov     ebx, [_base]
1511
        mov     edx, [_len]
1522
        mov     edx, [_len]
1512
.next:
1523
.next:
1513
        mov     ecx, edx
1524
        mov     ecx, edx
1514
;        jecxz   .error
1525
;        jecxz   .error
1515
        test    ecx, ecx
1526
        test    ecx, ecx
1516
        jz      .not_found
1527
        jz      .not_found
1517
        shr     ecx, 1
1528
        shr     ecx, 1
1518
        movbe   esi, [ebx+ecx*sizeof.xfs_dir2_leaf_entry+xfs_dir2_leaf_entry.hashval]
1529
        movbe   esi, [ebx+ecx*sizeof.xfs_dir2_leaf_entry+xfs_dir2_leaf_entry.hashval]
1519
        cmp     eax, esi
1530
        cmp     eax, esi
1520
        jb      .below
1531
        jb      .below
1521
        ja      .above
1532
        ja      .above
1522
        movbe   eax, [ebx+ecx*sizeof.xfs_dir2_leaf_entry+xfs_dir2_leaf_entry.address]
1533
        movbe   eax, [ebx+ecx*sizeof.xfs_dir2_leaf_entry+xfs_dir2_leaf_entry.address]
1523
        ret
1534
        ret
1524
.below:
1535
.below:
1525
        mov     edx, ecx
1536
        mov     edx, ecx
1526
        jmp     .next
1537
        jmp     .next
1527
.above:
1538
.above:
1528
        lea     ebx, [ebx+(ecx+1)*sizeof.xfs_dir2_leaf_entry]
1539
        lea     ebx, [ebx+(ecx+1)*sizeof.xfs_dir2_leaf_entry]
1529
        sub     edx, ecx
1540
        sub     edx, ecx
1530
        dec     edx
1541
        dec     edx
1531
        jmp     .next
1542
        jmp     .next
1532
.not_found:
1543
.not_found:
1533
        movi    eax, ERROR_FILE_NOT_FOUND
1544
        movi    eax, ERROR_FILE_NOT_FOUND
1534
        test    esp, esp
1545
        test    esp, esp
1535
        ret
1546
        ret
1536
endp
1547
endp
1537
 
1548
 
1538
 
1549
 
1539
;----------------------------------------------------------------
1550
;----------------------------------------------------------------
1540
; xfs_GetFileInfo: XFS implementation of getting file info
1551
; xfs_GetFileInfo: XFS implementation of getting file info
1541
; in:  ebp = pointer to XFS structure
1552
; in:  ebp = pointer to XFS structure
1542
; in:  esi = name
1553
; in:  esi = name
1543
; in:  ebx = pointer to parameters from sysfunc 70
1554
; in:  ebx = pointer to parameters from sysfunc 70
1544
; out: eax, ebx = return values for sysfunc 70
1555
; out: eax, ebx = return values for sysfunc 70
1545
;----------------------------------------------------------------
1556
;----------------------------------------------------------------
1546
proc xfs_GetFileInfo uses ecx edx esi edi
1557
proc xfs_GetFileInfo uses ecx edx esi edi
1547
        call    xfs._.lock
1558
        call    xfs._.lock
1548
        stdcall xfs_get_inode, esi
1559
        stdcall xfs_get_inode, esi
1549
        jnz     .error
1560
        jnz     .error
1550
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.cur_inode]
1561
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.cur_inode]
1551
        test    eax, eax
1562
        test    eax, eax
1552
        movi    eax, ERROR_FS_FAIL
1563
        movi    eax, ERROR_FS_FAIL
1553
        jnz     .error
1564
        jnz     .error
1554
        stdcall xfs_get_inode_info, edx, [ebx+f70s5arg.buf]
1565
        stdcall xfs_get_inode_info, edx, [ebx+f70s5arg.buf]
1555
.quit:
1566
.quit:
1556
        call    xfs._.unlock
1567
        call    xfs._.unlock
1557
        xor     eax, eax
1568
        xor     eax, eax
1558
        ret
1569
        ret
1559
.error:
1570
.error:
1560
        push    eax
1571
        push    eax
1561
        call    xfs._.unlock
1572
        call    xfs._.unlock
1562
        pop     eax
1573
        pop     eax
1563
        ret
1574
        ret
1564
endp
1575
endp
1565
 
1576
 
1566
 
1577
 
1567
proc xfs._.file.read_extent uses ebx ecx edx, _callback, _callback_data
1578
proc xfs._.file.read_extent uses ebx ecx edx, _callback, _callback_data
1568
        mov     eax, [ebp+XFS.file_offset.lo]
1579
        mov     eax, [ebp+XFS.file_offset.lo]
1569
        mov     edx, [ebp+XFS.file_offset.hi]
1580
        mov     edx, [ebp+XFS.file_offset.hi]
1570
        mov     esi, [ebp+XFS.extent.br_startoff.lo]
1581
        mov     esi, [ebp+XFS.extent.br_startoff.lo]
1571
        mov     edi, [ebp+XFS.extent.br_startoff.hi]
1582
        mov     edi, [ebp+XFS.extent.br_startoff.hi]
1572
        mov     ecx, [ebp+XFS.blocklog]
1583
        mov     ecx, [ebp+XFS.blocklog]
1573
        shld    edi, esi, cl
1584
        shld    edi, esi, cl
1574
        shl     esi, cl
1585
        shl     esi, cl
1575
        cmp     edx, edi
1586
        cmp     edx, edi
1576
        jb      .hole
1587
        jb      .hole
1577
        ja      .try_head
1588
        ja      .try_head
1578
        cmp     eax, esi
1589
        cmp     eax, esi
1579
        ja      .try_head
1590
        ja      .try_head
1580
        jz      .try_match
1591
        jz      .try_match
1581
.hole:
1592
.hole:
1582
        sub     esi, eax
1593
        sub     esi, eax
1583
        sbb     edi, edx
1594
        sbb     edi, edx
1584
        movi    ecx, -1
1595
        movi    ecx, -1
1585
        test    edi, edi
1596
        test    edi, edi
1586
        jnz     @f
1597
        jnz     @f
1587
        mov     ecx, esi
1598
        mov     ecx, esi
1588
@@:
1599
@@:
1589
        cmp     ecx, [ebp+XFS.bytes_to_read]
1600
        cmp     ecx, [ebp+XFS.bytes_to_read]
1590
        jbe     @f
1601
        jbe     @f
1591
        mov     ecx, [ebp+XFS.bytes_to_read]
1602
        mov     ecx, [ebp+XFS.bytes_to_read]
1592
@@:
1603
@@:
1593
        mov     edi, [ebp+XFS.file_buffer]
1604
        mov     edi, [ebp+XFS.file_buffer]
1594
        xor     eax, eax
1605
        xor     eax, eax
1595
        sub     [ebp+XFS.bytes_to_read], ecx
1606
        sub     [ebp+XFS.bytes_to_read], ecx
1596
        sub     [ebp+XFS.bytes_left_in_file.lo], ecx
1607
        sub     [ebp+XFS.bytes_left_in_file.lo], ecx
1597
        sbb     [ebp+XFS.bytes_left_in_file.hi], 0
1608
        sbb     [ebp+XFS.bytes_left_in_file.hi], 0
1598
        add     [ebp+XFS.bytes_read], ecx
1609
        add     [ebp+XFS.bytes_read], ecx
1599
        add     [ebp+XFS.file_buffer], ecx
1610
        add     [ebp+XFS.file_buffer], ecx
1600
        add     [ebp+XFS.file_offset.lo], ecx
1611
        add     [ebp+XFS.file_offset.lo], ecx
1601
        adc     [ebp+XFS.file_offset.hi], 0
1612
        adc     [ebp+XFS.file_offset.hi], 0
1602
        rep stosb
1613
        rep stosb
1603
        cmp     [ebp+XFS.bytes_to_read], 0
1614
        cmp     [ebp+XFS.bytes_to_read], 0
1604
        jz      .quit
1615
        jz      .quit
1605
        jmp     .try_match
1616
        jmp     .try_match
1606
.try_head:
1617
.try_head:
1607
        mov     eax, [ebp+XFS.file_offset.lo]
1618
        mov     eax, [ebp+XFS.file_offset.lo]
1608
        mov     ecx, [ebp+XFS.blocksize]
1619
        mov     ecx, [ebp+XFS.blocksize]
1609
        dec     ecx
1620
        dec     ecx
1610
        test    eax, ecx
1621
        test    eax, ecx
1611
        jz      .try_match
1622
        jz      .try_match
1612
.head:
1623
.head:
1613
        mov     eax, [ebp+XFS.extent.br_startblock.lo]
1624
        mov     eax, [ebp+XFS.extent.br_startblock.lo]
1614
        mov     edx, [ebp+XFS.extent.br_startblock.hi]
1625
        mov     edx, [ebp+XFS.extent.br_startblock.hi]
1615
        mov     ebx, [ebp+XFS.cur_block_data]
1626
        mov     ebx, [ebp+XFS.cur_block_data]
1616
        stdcall xfs._.read_block
1627
        stdcall xfs._.read_block
1617
        mov     esi, [ebp+XFS.cur_block_data]
1628
        mov     esi, [ebp+XFS.cur_block_data]
1618
        mov     edi, [ebp+XFS.file_buffer]
1629
        mov     edi, [ebp+XFS.file_buffer]
1619
        mov     eax, [ebp+XFS.file_offset.lo]
1630
        mov     eax, [ebp+XFS.file_offset.lo]
1620
        mov     ecx, [ebp+XFS.blocksize]
1631
        mov     ecx, [ebp+XFS.blocksize]
1621
        dec     ecx
1632
        dec     ecx
1622
        and     eax, ecx
1633
        and     eax, ecx
1623
        add     esi, eax
1634
        add     esi, eax
1624
        inc     ecx
1635
        inc     ecx
1625
        sub     ecx, eax
1636
        sub     ecx, eax
1626
        cmp     ecx, [ebp+XFS.bytes_to_read]
1637
        cmp     ecx, [ebp+XFS.bytes_to_read]
1627
        jbe     @f
1638
        jbe     @f
1628
        mov     ecx, [ebp+XFS.bytes_to_read]
1639
        mov     ecx, [ebp+XFS.bytes_to_read]
1629
@@:
1640
@@:
1630
        sub     [ebp+XFS.bytes_to_read], ecx
1641
        sub     [ebp+XFS.bytes_to_read], ecx
1631
        sub     [ebp+XFS.bytes_left_in_file.lo], ecx
1642
        sub     [ebp+XFS.bytes_left_in_file.lo], ecx
1632
        sbb     [ebp+XFS.bytes_left_in_file.hi], 0
1643
        sbb     [ebp+XFS.bytes_left_in_file.hi], 0
1633
        add     [ebp+XFS.bytes_read], ecx
1644
        add     [ebp+XFS.bytes_read], ecx
1634
        add     [ebp+XFS.file_buffer], ecx
1645
        add     [ebp+XFS.file_buffer], ecx
1635
        add     [ebp+XFS.file_offset.lo], ecx
1646
        add     [ebp+XFS.file_offset.lo], ecx
1636
        adc     [ebp+XFS.file_offset.hi], 0
1647
        adc     [ebp+XFS.file_offset.hi], 0
1637
        rep movsb
1648
        rep movsb
1638
        add     [ebp+XFS.extent.br_startoff.lo], 1
1649
        add     [ebp+XFS.extent.br_startoff.lo], 1
1639
        adc     [ebp+XFS.extent.br_startoff.hi], 0
1650
        adc     [ebp+XFS.extent.br_startoff.hi], 0
1640
        add     [ebp+XFS.extent.br_startblock.lo], 1
1651
        add     [ebp+XFS.extent.br_startblock.lo], 1
1641
        adc     [ebp+XFS.extent.br_startblock.hi], 0
1652
        adc     [ebp+XFS.extent.br_startblock.hi], 0
1642
        dec     [ebp+XFS.extent.br_blockcount]
1653
        dec     [ebp+XFS.extent.br_blockcount]
1643
;        cmp     [ebp+XFS.bytes_to_read], 0
1654
;        cmp     [ebp+XFS.bytes_to_read], 0
1644
        jz      .quit
1655
        jz      .quit
1645
.try_match:
1656
.try_match:
1646
        mov     eax, [ebp+XFS.bytes_to_read]
1657
        mov     eax, [ebp+XFS.bytes_to_read]
1647
        test    eax, eax
1658
        test    eax, eax
1648
        jz      .quit
1659
        jz      .quit
1649
        cmp     eax, [ebp+XFS.blocksize]
1660
        cmp     eax, [ebp+XFS.blocksize]
1650
        jb      .tail
1661
        jb      .tail
1651
        mov     ecx, [ebp+XFS.blocklog]
1662
        mov     ecx, [ebp+XFS.blocklog]
1652
        shr     eax, cl
1663
        shr     eax, cl
1653
        cmp     eax, [ebp+XFS.extent.br_blockcount]
1664
        cmp     eax, [ebp+XFS.extent.br_blockcount]
1654
        jbe     @f
1665
        jbe     @f
1655
        mov     eax, [ebp+XFS.extent.br_blockcount]
1666
        mov     eax, [ebp+XFS.extent.br_blockcount]
1656
@@:
1667
@@:
1657
        mov     ecx, eax
1668
        mov     ecx, eax
1658
        mov     eax, [ebp+XFS.extent.br_startblock.lo]
1669
        mov     eax, [ebp+XFS.extent.br_startblock.lo]
1659
        mov     edx, [ebp+XFS.extent.br_startblock.hi]
1670
        mov     edx, [ebp+XFS.extent.br_startblock.hi]
1660
        mov     ebx, [ebp+XFS.file_buffer]
1671
        mov     ebx, [ebp+XFS.file_buffer]
1661
        push    ecx
1672
        push    ecx
1662
        stdcall xfs._.read_blocks
1673
        stdcall xfs._.read_blocks
1663
        pop     eax
1674
        pop     eax
1664
        add     [ebp+XFS.extent.br_startoff.lo], eax
1675
        add     [ebp+XFS.extent.br_startoff.lo], eax
1665
        adc     [ebp+XFS.extent.br_startoff.hi], 0
1676
        adc     [ebp+XFS.extent.br_startoff.hi], 0
1666
        add     [ebp+XFS.extent.br_startblock.lo], eax
1677
        add     [ebp+XFS.extent.br_startblock.lo], eax
1667
        adc     [ebp+XFS.extent.br_startblock.hi], 0
1678
        adc     [ebp+XFS.extent.br_startblock.hi], 0
1668
        sub     [ebp+XFS.extent.br_blockcount], eax
1679
        sub     [ebp+XFS.extent.br_blockcount], eax
1669
        imul    eax, [ebp+XFS.blocksize]
1680
        imul    eax, [ebp+XFS.blocksize]
1670
        sub     [ebp+XFS.bytes_to_read], eax
1681
        sub     [ebp+XFS.bytes_to_read], eax
1671
        sub     [ebp+XFS.bytes_left_in_file.lo], eax
1682
        sub     [ebp+XFS.bytes_left_in_file.lo], eax
1672
        sbb     [ebp+XFS.bytes_left_in_file.hi], 0
1683
        sbb     [ebp+XFS.bytes_left_in_file.hi], 0
1673
        add     [ebp+XFS.bytes_read], eax
1684
        add     [ebp+XFS.bytes_read], eax
1674
        add     [ebp+XFS.file_buffer], eax
1685
        add     [ebp+XFS.file_buffer], eax
1675
        add     [ebp+XFS.file_offset.lo], eax
1686
        add     [ebp+XFS.file_offset.lo], eax
1676
        adc     [ebp+XFS.file_offset.hi], 0
1687
        adc     [ebp+XFS.file_offset.hi], 0
1677
;        cmp     [ebp+XFS.bytes_to_read], 0
1688
;        cmp     [ebp+XFS.bytes_to_read], 0
1678
        cmp     [ebp+XFS.extent.br_blockcount], 0
1689
        cmp     [ebp+XFS.extent.br_blockcount], 0
1679
        jz      .quit
1690
        jz      .quit
1680
.tail:
1691
.tail:
1681
        mov     eax, [ebp+XFS.extent.br_startblock.lo]
1692
        mov     eax, [ebp+XFS.extent.br_startblock.lo]
1682
        mov     edx, [ebp+XFS.extent.br_startblock.hi]
1693
        mov     edx, [ebp+XFS.extent.br_startblock.hi]
1683
        mov     ebx, [ebp+XFS.cur_block_data]
1694
        mov     ebx, [ebp+XFS.cur_block_data]
1684
        stdcall xfs._.read_block
1695
        stdcall xfs._.read_block
1685
        mov     ecx, [ebp+XFS.bytes_to_read]
1696
        mov     ecx, [ebp+XFS.bytes_to_read]
1686
        cmp     [ebp+XFS.bytes_left_in_file.hi], 0
1697
        cmp     [ebp+XFS.bytes_left_in_file.hi], 0
1687
        jnz     @f
1698
        jnz     @f
1688
        cmp     ecx, [ebp+XFS.bytes_left_in_file.lo]
1699
        cmp     ecx, [ebp+XFS.bytes_left_in_file.lo]
1689
        jbe     @f
1700
        jbe     @f
1690
        mov     ecx, [ebp+XFS.bytes_left_in_file.lo]
1701
        mov     ecx, [ebp+XFS.bytes_left_in_file.lo]
1691
@@:
1702
@@:
1692
        mov     esi, [ebp+XFS.cur_block_data]
1703
        mov     esi, [ebp+XFS.cur_block_data]
1693
        mov     edi, [ebp+XFS.file_buffer]
1704
        mov     edi, [ebp+XFS.file_buffer]
1694
        mov     eax, ecx
1705
        mov     eax, ecx
1695
        rep movsb
1706
        rep movsb
1696
        add     [ebp+XFS.bytes_read], eax
1707
        add     [ebp+XFS.bytes_read], eax
1697
        sub     [ebp+XFS.bytes_to_read], eax
1708
        sub     [ebp+XFS.bytes_to_read], eax
1698
        sub     [ebp+XFS.bytes_left_in_file.lo], eax
1709
        sub     [ebp+XFS.bytes_left_in_file.lo], eax
1699
        sbb     [ebp+XFS.bytes_left_in_file.hi], 0
1710
        sbb     [ebp+XFS.bytes_left_in_file.hi], 0
1700
        add     [ebp+XFS.file_buffer], eax
1711
        add     [ebp+XFS.file_buffer], eax
1701
        add     [ebp+XFS.file_offset.lo], eax
1712
        add     [ebp+XFS.file_offset.lo], eax
1702
        adc     [ebp+XFS.file_offset.hi], 0
1713
        adc     [ebp+XFS.file_offset.hi], 0
1703
        add     [ebp+XFS.extent.br_startoff.lo], 1
1714
        add     [ebp+XFS.extent.br_startoff.lo], 1
1704
        adc     [ebp+XFS.extent.br_startoff.hi], 0
1715
        adc     [ebp+XFS.extent.br_startoff.hi], 0
1705
        add     [ebp+XFS.extent.br_startblock.lo], 1
1716
        add     [ebp+XFS.extent.br_startblock.lo], 1
1706
        adc     [ebp+XFS.extent.br_startblock.hi], 0
1717
        adc     [ebp+XFS.extent.br_startblock.hi], 0
1707
        dec     [ebp+XFS.extent.br_blockcount]
1718
        dec     [ebp+XFS.extent.br_blockcount]
1708
.quit:
1719
.quit:
1709
        mov     esi, [ebp+XFS.extent.br_startoff.lo]
1720
        mov     esi, [ebp+XFS.extent.br_startoff.lo]
1710
        mov     edi, [ebp+XFS.extent.br_startoff.hi]
1721
        mov     edi, [ebp+XFS.extent.br_startoff.hi]
1711
        movi    eax, ERROR_SUCCESS
1722
        movi    eax, ERROR_SUCCESS
1712
        cmp     esp, esp
1723
        cmp     esp, esp
1713
        ret
1724
        ret
1714
endp
1725
endp
1715
 
1726
 
1716
 
1727
 
1717
;----------------------------------------------------------------
1728
;----------------------------------------------------------------
1718
; in:  ebp = pointer to XFS structure
1729
; in:  ebp = pointer to XFS structure
1719
; in:  esi = name
1730
; in:  esi = name
1720
; in:  ebx = pointer to parameters from sysfunc 70
1731
; in:  ebx = pointer to parameters from sysfunc 70
1721
; out: eax, ebx = return values for sysfunc 70
1732
; out: eax, ebx = return values for sysfunc 70
1722
;----------------------------------------------------------------
1733
;----------------------------------------------------------------
1723
proc xfs_Read uses ecx edx esi edi
1734
proc xfs_Read uses ecx edx esi edi
1724
locals
1735
locals
1725
        .offset_begin DQ ?
1736
        .offset_begin DQ ?
1726
        .offset_end   DQ ?
1737
        .offset_end   DQ ?
1727
endl
1738
endl
1728
        call    xfs._.lock
1739
        call    xfs._.lock
1729
        mov     [ebp+XFS.bytes_read], 0
1740
        mov     [ebp+XFS.bytes_read], 0
1730
        mov     eax, [ebx+f70s0arg.count]
1741
        mov     eax, [ebx+f70s0arg.count]
1731
        mov     [ebp+XFS.bytes_to_read], eax
1742
        mov     [ebp+XFS.bytes_to_read], eax
1732
        test    eax, eax
1743
        test    eax, eax
1733
        jz      .quit
1744
        jz      .quit
1734
        mov     eax, [ebx+f70s0arg.buf]
1745
        mov     eax, [ebx+f70s0arg.buf]
1735
        mov     [ebp+XFS.file_buffer], eax
1746
        mov     [ebp+XFS.file_buffer], eax
1736
        mov     eax, [ebx+f70s0arg.offset.hi]
1747
        mov     eax, [ebx+f70s0arg.offset.hi]
1737
        mov     [ebp+XFS.file_offset.hi], eax
1748
        mov     [ebp+XFS.file_offset.hi], eax
1738
        mov     eax, [ebx+f70s0arg.offset.lo]
1749
        mov     eax, [ebx+f70s0arg.offset.lo]
1739
        mov     [ebp+XFS.file_offset.lo], eax
1750
        mov     [ebp+XFS.file_offset.lo], eax
1740
 
1751
 
1741
        stdcall xfs_get_inode, esi
1752
        stdcall xfs_get_inode, esi
1742
        jnz     .error
1753
        jnz     .error
1743
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.cur_inode]
1754
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.cur_inode]
1744
        test    eax, eax
1755
        test    eax, eax
1745
        movi    eax, ERROR_FS_FAIL
1756
        movi    eax, ERROR_FS_FAIL
1746
        jnz     .error
1757
        jnz     .error
1747
        mov     [ebp+XFS.cur_inode_save], edx
1758
        mov     [ebp+XFS.cur_inode_save], edx
1748
        mov     ebx, edx
1759
        mov     ebx, edx
1749
        ; precompute .offset_begin
1760
        ; precompute .offset_begin
1750
        mov     esi, [ebp+XFS.file_offset.lo]
1761
        mov     esi, [ebp+XFS.file_offset.lo]
1751
        mov     edi, [ebp+XFS.file_offset.hi]
1762
        mov     edi, [ebp+XFS.file_offset.hi]
1752
        mov     ecx, [ebp+XFS.blocklog]
1763
        mov     ecx, [ebp+XFS.blocklog]
1753
        shrd    esi, edi, cl
1764
        shrd    esi, edi, cl
1754
        shr     edi, cl
1765
        shr     edi, cl
1755
        mov     [.offset_begin.lo], esi
1766
        mov     [.offset_begin.lo], esi
1756
        mov     [.offset_begin.hi], edi
1767
        mov     [.offset_begin.hi], edi
1757
        ; precompute .offset_end
1768
        ; precompute .offset_end
1758
        mov     esi, [ebp+XFS.file_offset.lo]
1769
        mov     esi, [ebp+XFS.file_offset.lo]
1759
        mov     edi, [ebp+XFS.file_offset.hi]
1770
        mov     edi, [ebp+XFS.file_offset.hi]
1760
        add     esi, [ebp+XFS.bytes_to_read]
1771
        add     esi, [ebp+XFS.bytes_to_read]
1761
        adc     edi, 0
1772
        adc     edi, 0
1762
        mov     ecx, [ebp+XFS.blocksize]
1773
        mov     ecx, [ebp+XFS.blocksize]
1763
        dec     ecx
1774
        dec     ecx
1764
        add     esi, ecx
1775
        add     esi, ecx
1765
        adc     edi, 0
1776
        adc     edi, 0
1766
        mov     ecx, [ebp+XFS.blocklog]
1777
        mov     ecx, [ebp+XFS.blocklog]
1767
        shrd    esi, edi, cl
1778
        shrd    esi, edi, cl
1768
        shr     edi, cl
1779
        shr     edi, cl
1769
        mov     [.offset_end.lo], esi
1780
        mov     [.offset_end.lo], esi
1770
        mov     [.offset_end.hi], edi
1781
        mov     [.offset_end.hi], edi
1771
 
1782
 
1772
        movbe   ecx, [ebx+xfs_inode.di_core.di_size.hi]
1783
        movbe   ecx, [ebx+xfs_inode.di_core.di_size.hi]
1773
        movbe   edx, [ebx+xfs_inode.di_core.di_size.lo]
1784
        movbe   edx, [ebx+xfs_inode.di_core.di_size.lo]
1774
        mov     [ebp+XFS.bytes_left_in_file.lo], ecx
1785
        mov     [ebp+XFS.bytes_left_in_file.lo], ecx
1775
        mov     [ebp+XFS.bytes_left_in_file.hi], edx
1786
        mov     [ebp+XFS.bytes_left_in_file.hi], edx
1776
 
1787
 
1777
        sub     ecx, [ebp+XFS.file_offset.lo]
1788
        sub     ecx, [ebp+XFS.file_offset.lo]
1778
        sbb     edx, [ebp+XFS.file_offset.hi]
1789
        sbb     edx, [ebp+XFS.file_offset.hi]
1779
        movi    eax, ERROR_END_OF_FILE
1790
        movi    eax, ERROR_END_OF_FILE
1780
        jb      .error
1791
        jb      .error
1781
        mov     [ebp+XFS.eof], 0
1792
        mov     [ebp+XFS.eof], 0
1782
        test    edx, edx
1793
        test    edx, edx
1783
        jnz     @f
1794
        jnz     @f
1784
        cmp     ecx, [ebp+XFS.bytes_to_read]
1795
        cmp     ecx, [ebp+XFS.bytes_to_read]
1785
        jae     @f
1796
        jae     @f
1786
        mov     [ebp+XFS.eof], ERROR_END_OF_FILE
1797
        mov     [ebp+XFS.eof], ERROR_END_OF_FILE
1787
        mov     [ebp+XFS.bytes_to_read], ecx
1798
        mov     [ebp+XFS.bytes_to_read], ecx
1788
@@:
1799
@@:
1789
 
1800
 
1790
        cmp     [ebx+xfs_inode.di_core.di_format], XFS_DINODE_FMT_BTREE
1801
        cmp     [ebx+xfs_inode.di_core.di_format], XFS_DINODE_FMT_BTREE
1791
        jz      .btree
1802
        jz      .btree
1792
.extent_list:
1803
.extent_list:
1793
        mov     eax, ebx
1804
        mov     eax, ebx
1794
        add     eax, [ebp+XFS.inode_core_size]
1805
        add     eax, [ebp+XFS.inode_core_size]
1795
        mov     edx, [ebp+XFS.nextents_offset]
1806
        mov     edx, [ebp+XFS.nextents_offset]
1796
        movbe   edx, [ebx+edx]
1807
        movbe   edx, [ebx+edx]
1797
        mov     ecx, [.offset_begin.lo]
1808
        mov     ecx, [.offset_begin.lo]
1798
        mov     [ebp+XFS.offset_begin.lo], ecx
1809
        mov     [ebp+XFS.offset_begin.lo], ecx
1799
        mov     ecx, [.offset_begin.hi]
1810
        mov     ecx, [.offset_begin.hi]
1800
        mov     [ebp+XFS.offset_begin.hi], ecx
1811
        mov     [ebp+XFS.offset_begin.hi], ecx
1801
        mov     ecx, [.offset_end.lo]
1812
        mov     ecx, [.offset_end.lo]
1802
        mov     [ebp+XFS.offset_end.lo], ecx
1813
        mov     [ebp+XFS.offset_end.lo], ecx
1803
        mov     ecx, [.offset_end.hi]
1814
        mov     ecx, [.offset_end.hi]
1804
        mov     [ebp+XFS.offset_end.hi], ecx
1815
        mov     [ebp+XFS.offset_end.hi], ecx
1805
        stdcall xfs._.walk_extent_list, edx, eax, xfs._.file.read_extent, 0, 0
1816
        stdcall xfs._.walk_extent_list, edx, eax, xfs._.file.read_extent, 0, 0
1806
        jnz     .error
1817
        jnz     .error
1807
        jmp     .hole_check
1818
        jmp     .hole_check
1808
.btree:
1819
.btree:
1809
        mov     eax, [ebp+XFS.inodesize]
1820
        mov     eax, [ebp+XFS.inodesize]
1810
        sub     eax, [ebp+XFS.inode_core_size]
1821
        sub     eax, [ebp+XFS.inode_core_size]
1811
        movzx   ecx, [ebx+xfs_inode.di_core.di_forkoff]
1822
        movzx   ecx, [ebx+xfs_inode.di_core.di_forkoff]
1812
        jecxz   @f
1823
        jecxz   @f
1813
        shl     ecx, 3
1824
        shl     ecx, 3
1814
        mov     eax, ecx
1825
        mov     eax, ecx
1815
@@:
1826
@@:
1816
        mov     edx, ebx
1827
        mov     edx, ebx
1817
        add     edx, [ebp+XFS.inode_core_size]
1828
        add     edx, [ebp+XFS.inode_core_size]
1818
        mov     ecx, [.offset_begin.lo]
1829
        mov     ecx, [.offset_begin.lo]
1819
        mov     [ebp+XFS.offset_begin.lo], ecx
1830
        mov     [ebp+XFS.offset_begin.lo], ecx
1820
        mov     ecx, [.offset_begin.hi]
1831
        mov     ecx, [.offset_begin.hi]
1821
        mov     [ebp+XFS.offset_begin.hi], ecx
1832
        mov     [ebp+XFS.offset_begin.hi], ecx
1822
        mov     ecx, [.offset_end.lo]
1833
        mov     ecx, [.offset_end.lo]
1823
        mov     [ebp+XFS.offset_end.lo], ecx
1834
        mov     [ebp+XFS.offset_end.lo], ecx
1824
        mov     ecx, [.offset_end.hi]
1835
        mov     ecx, [.offset_end.hi]
1825
        mov     [ebp+XFS.offset_end.hi], ecx
1836
        mov     [ebp+XFS.offset_end.hi], ecx
1826
        stdcall xfs._.walk_btree, edx, eax, xfs._.file.read_extent, 0, 0, 1
1837
        stdcall xfs._.walk_btree, edx, eax, xfs._.file.read_extent, 0, 0, 1
1827
.hole_check:
1838
.hole_check:
1828
        cmp     [ebp+XFS.bytes_left_in_file.hi], 0
1839
        cmp     [ebp+XFS.bytes_left_in_file.hi], 0
1829
        jnz     @f
1840
        jnz     @f
1830
        cmp     [ebp+XFS.bytes_left_in_file.lo], 0
1841
        cmp     [ebp+XFS.bytes_left_in_file.lo], 0
1831
        jz      .hole_done
1842
        jz      .hole_done
1832
@@:
1843
@@:
1833
        cmp     [ebp+XFS.bytes_to_read], 0
1844
        cmp     [ebp+XFS.bytes_to_read], 0
1834
        jz      .hole_done
1845
        jz      .hole_done
1835
        mov     ebx, [ebp+XFS.cur_inode_save]
1846
        mov     ebx, [ebp+XFS.cur_inode_save]
1836
        movbe   edx, [ebx+xfs_inode.di_core.di_size.lo]
1847
        movbe   edx, [ebx+xfs_inode.di_core.di_size.lo]
1837
        movbe   eax, [ebx+xfs_inode.di_core.di_size.hi]
1848
        movbe   eax, [ebx+xfs_inode.di_core.di_size.hi]
1838
        sub     eax, [ebp+XFS.file_offset.lo]
1849
        sub     eax, [ebp+XFS.file_offset.lo]
1839
        sbb     edx, [ebp+XFS.file_offset.hi]
1850
        sbb     edx, [ebp+XFS.file_offset.hi]
1840
        jc      .hole_done
1851
        jc      .hole_done
1841
        mov     ecx, [ebp+XFS.bytes_to_read]
1852
        mov     ecx, [ebp+XFS.bytes_to_read]
1842
        test    edx, edx
1853
        test    edx, edx
1843
        jnz     .hole_read
1854
        jnz     .hole_read
1844
        cmp     eax, [ebp+XFS.bytes_to_read]
1855
        cmp     eax, [ebp+XFS.bytes_to_read]
1845
        jae     .hole_read
1856
        jae     .hole_read
1846
        mov     ecx, eax
1857
        mov     ecx, eax
1847
        jmp     .hole_read
1858
        jmp     .hole_read
1848
.hole_read:
1859
.hole_read:
1849
        sub     [ebp+XFS.bytes_to_read], ecx
1860
        sub     [ebp+XFS.bytes_to_read], ecx
1850
        add     [ebp+XFS.bytes_read], ecx
1861
        add     [ebp+XFS.bytes_read], ecx
1851
        mov     edi, [ebp+XFS.file_buffer]
1862
        mov     edi, [ebp+XFS.file_buffer]
1852
        xor     eax, eax
1863
        xor     eax, eax
1853
        rep stosb
1864
        rep stosb
1854
.hole_done:
1865
.hole_done:
1855
.quit:
1866
.quit:
1856
        mov     eax, [ebp+XFS.eof]
1867
        mov     eax, [ebp+XFS.eof]
1857
.error:
1868
.error:
1858
        push    eax
1869
        push    eax
1859
        call    xfs._.unlock
1870
        call    xfs._.unlock
1860
        pop     eax
1871
        pop     eax
1861
        mov     ebx, [ebp+XFS.bytes_read]
1872
        mov     ebx, [ebp+XFS.bytes_read]
1862
        ret
1873
        ret
1863
endp
1874
endp
1864
 
1875
 
1865
 
1876
 
1866
proc xfs._.leafn_calc_entries uses ebx ecx edx esi edi, _cur_dirblock, _offset_lo, _offset_hi, _arg
1877
proc xfs._.leafn_calc_entries uses ebx ecx edx esi edi, _cur_dirblock, _offset_lo, _offset_hi, _arg
1867
        mov     edx, [_cur_dirblock]
1878
        mov     edx, [_cur_dirblock]
1868
        movzx   eax, [ebp+XFS.da_node_magic]
1879
        movzx   eax, [ebp+XFS.da_node_magic]
1869
        cmp     [edx+xfs_dir2_leaf.hdr.info.magic], ax
1880
        cmp     [edx+xfs_dir2_leaf.hdr.info.magic], ax
1870
        jz      .quit
1881
        jz      .quit
1871
        cmp     [ebp+XFS.version], 5
1882
        cmp     [ebp+XFS.version], 5
1872
        jnz     @f
1883
        jnz     @f
1873
        add     edx, xfs_dir3_leaf.hdr.count-xfs_dir2_leaf.hdr.count
1884
        add     edx, xfs_dir3_leaf.hdr.count-xfs_dir2_leaf.hdr.count
1874
@@:
1885
@@:
1875
        movzx   eax, [edx+xfs_dir2_leaf.hdr.count]
1886
        movzx   eax, [edx+xfs_dir2_leaf.hdr.count]
1876
        movzx   ecx, [edx+xfs_dir2_leaf.hdr.stale]
1887
        movzx   ecx, [edx+xfs_dir2_leaf.hdr.stale]
1877
        xchg    al, ah
1888
        xchg    al, ah
1878
        xchg    cl, ch
1889
        xchg    cl, ch
1879
        sub     eax, ecx
1890
        sub     eax, ecx
1880
        add     [ebp+XFS.entries_read], eax
1891
        add     [ebp+XFS.entries_read], eax
1881
.quit:
1892
.quit:
1882
        movi    eax, ERROR_SUCCESS
1893
        movi    eax, ERROR_SUCCESS
1883
        cmp     esp, esp
1894
        cmp     esp, esp
1884
        ret
1895
        ret
1885
endp
1896
endp
1886
 
1897
 
1887
 
1898
 
1888
proc xfs._.get_before_by_hashval uses ebx edx esi edi, _base, _count, _hash
1899
proc xfs._.get_before_by_hashval uses ebx edx esi edi, _base, _count, _hash
1889
        mov     edi, [_hash]
1900
        mov     edi, [_hash]
1890
        mov     edx, [_count]
1901
        mov     edx, [_count]
1891
        xor     ecx, ecx
1902
        xor     ecx, ecx
1892
.node.next:
1903
.node.next:
1893
        movbe   eax, [ebx+xfs_da_intnode.btree+ecx*sizeof.xfs_da_node_entry+xfs_da_node_entry.hashval]
1904
        movbe   eax, [ebx+xfs_da_intnode.btree+ecx*sizeof.xfs_da_node_entry+xfs_da_node_entry.hashval]
1894
        cmp     [ebp+XFS.version], 5
1905
        cmp     [ebp+XFS.version], 5
1895
        jnz     @f
1906
        jnz     @f
1896
        movbe   eax, [ebx+xfs_da3_intnode.btree+ecx*sizeof.xfs_da_node_entry+xfs_da_node_entry.hashval]
1907
        movbe   eax, [ebx+xfs_da3_intnode.btree+ecx*sizeof.xfs_da_node_entry+xfs_da_node_entry.hashval]
1897
@@:
1908
@@:
1898
        cmp     eax, edi
1909
        cmp     eax, edi
1899
        jae     .node.leaf_found
1910
        jae     .node.leaf_found
1900
        inc     ecx
1911
        inc     ecx
1901
        cmp     ecx, edx
1912
        cmp     ecx, edx
1902
        jnz     .node.next
1913
        jnz     .node.next
1903
        movi    eax, ERROR_FILE_NOT_FOUND
1914
        movi    eax, ERROR_FILE_NOT_FOUND
1904
        test    esp, esp
1915
        test    esp, esp
1905
        jmp     .error
1916
        jmp     .error
1906
.node.leaf_found:
1917
.node.leaf_found:
1907
        movbe   eax, [ebx+xfs_da_intnode.btree+ecx*sizeof.xfs_da_node_entry+xfs_da_node_entry.before]
1918
        movbe   eax, [ebx+xfs_da_intnode.btree+ecx*sizeof.xfs_da_node_entry+xfs_da_node_entry.before]
1908
        cmp     [ebp+XFS.version], 5
1919
        cmp     [ebp+XFS.version], 5
1909
        jnz     @f
1920
        jnz     @f
1910
        movbe   eax, [ebx+xfs_da3_intnode.btree+ecx*sizeof.xfs_da_node_entry+xfs_da_node_entry.before]
1921
        movbe   eax, [ebx+xfs_da3_intnode.btree+ecx*sizeof.xfs_da_node_entry+xfs_da_node_entry.before]
1911
@@:
1922
@@:
1912
        jmp     .quit
1923
        jmp     .quit
1913
.error:
1924
.error:
1914
        test    esp, esp
1925
        test    esp, esp
1915
        ret
1926
        ret
1916
.quit:
1927
.quit:
1917
        cmp     esp, esp
1928
        cmp     esp, esp
1918
        ret
1929
        ret
1919
endp
1930
endp
1920
 
1931
 
1921
 
1932
 
1922
proc xfs._.long_btree.seek uses ebx esi edi, _ptr, _size
1933
proc xfs._.long_btree.seek uses ebx esi edi, _ptr, _size
1923
        mov     ebx, [_ptr]
1934
        mov     ebx, [_ptr]
1924
        mov     esi, [_size]
1935
        mov     esi, [_size]
1925
        sub     esi, sizeof.xfs_bmdr_block
1936
        sub     esi, sizeof.xfs_bmdr_block
1926
        shr     esi, 4
1937
        shr     esi, 4
1927
        shl     esi, 3
1938
        shl     esi, 3
1928
        movzx   eax, [ebx+xfs_bmdr_block.bb_level]
1939
        movzx   eax, [ebx+xfs_bmdr_block.bb_level]
1929
        movzx   ecx, [ebx+xfs_bmdr_block.bb_numrecs]
1940
        movzx   ecx, [ebx+xfs_bmdr_block.bb_numrecs]
1930
        xchg    cl, ch
1941
        xchg    cl, ch
1931
        add     ebx, sizeof.xfs_bmdr_block
1942
        add     ebx, sizeof.xfs_bmdr_block
1932
        jmp     .common
1943
        jmp     .common
1933
.not_root:
1944
.not_root:
1934
        mov     esi, [ebp+XFS.blocksize]
1945
        mov     esi, [ebp+XFS.blocksize]
1935
        sub     esi, [ebp+XFS.bmbt_block_size]
1946
        sub     esi, [ebp+XFS.bmbt_block_size]
1936
        shr     esi, 4
1947
        shr     esi, 4
1937
        shl     esi, 3
1948
        shl     esi, 3
1938
        movzx   eax, [ebx+xfs_bmbt_block.bb_level]
1949
        movzx   eax, [ebx+xfs_bmbt_block.bb_level]
1939
        movzx   ecx, [ebx+xfs_bmbt_block.bb_numrecs]
1950
        movzx   ecx, [ebx+xfs_bmbt_block.bb_numrecs]
1940
        xchg    cl, ch
1951
        xchg    cl, ch
1941
        add     ebx, [ebp+XFS.bmbt_block_size]
1952
        add     ebx, [ebp+XFS.bmbt_block_size]
1942
.common:
1953
.common:
1943
        test    eax, eax
1954
        test    eax, eax
1944
        jz      .leaf
1955
        jz      .leaf
1945
.node:
1956
.node:
1946
.next_rec:
1957
.next_rec:
1947
        dec     ecx
1958
        dec     ecx
1948
        js      .error
1959
        js      .error
1949
        movbe   eax, [ebx+ecx*sizeof.xfs_bmbt_key+xfs_bmbt_key.br_startoff.lo]
1960
        movbe   eax, [ebx+ecx*sizeof.xfs_bmbt_key+xfs_bmbt_key.br_startoff.lo]
1950
        cmp     [ebp+XFS.offset_begin.hi], eax
1961
        cmp     [ebp+XFS.offset_begin.hi], eax
1951
        ja      .node_found
1962
        ja      .node_found
1952
        jb      .next_rec
1963
        jb      .next_rec
1953
        movbe   eax, [ebx+ecx*sizeof.xfs_bmbt_key+xfs_bmbt_key.br_startoff.hi]
1964
        movbe   eax, [ebx+ecx*sizeof.xfs_bmbt_key+xfs_bmbt_key.br_startoff.hi]
1954
        cmp     [ebp+XFS.offset_begin.lo], eax
1965
        cmp     [ebp+XFS.offset_begin.lo], eax
1955
        jae     .node_found
1966
        jae     .node_found
1956
        jmp     .next_rec
1967
        jmp     .next_rec
1957
.node_found:
1968
.node_found:
1958
        add     ebx, esi
1969
        add     ebx, esi
1959
        movbe   edx, [ebx+ecx*sizeof.xfs_bmbt_ptr+xfs_bmbt_ptr.lo]
1970
        movbe   edx, [ebx+ecx*sizeof.xfs_bmbt_ptr+xfs_bmbt_ptr.lo]
1960
        movbe   eax, [ebx+ecx*sizeof.xfs_bmbt_ptr+xfs_bmbt_ptr.hi]
1971
        movbe   eax, [ebx+ecx*sizeof.xfs_bmbt_ptr+xfs_bmbt_ptr.hi]
1961
        mov     ebx, [ebp+XFS.cur_block]
1972
        mov     ebx, [ebp+XFS.cur_block]
1962
        stdcall xfs._.read_block
1973
        stdcall xfs._.read_block
1963
        test    eax, eax
1974
        test    eax, eax
1964
        jnz     .error
1975
        jnz     .error
1965
        mov     ebx, [ebp+XFS.cur_block]
1976
        mov     ebx, [ebp+XFS.cur_block]
1966
        jmp     .not_root
1977
        jmp     .not_root
1967
.leaf:
1978
.leaf:
1968
        jmp     .quit
1979
        jmp     .quit
1969
.error:
1980
.error:
1970
.quit:
1981
.quit:
1971
        ret
1982
        ret
1972
endp
1983
endp
1973
 
1984
 
1974
 
1985
 
1975
proc xfs._.walk_btree uses ebx esi edi, _ptr, _size, _callback_extent, _callback_block, _callback_data, _is_root
1986
proc xfs._.walk_btree uses ebx esi edi, _ptr, _size, _callback_extent, _callback_block, _callback_data, _is_root
1976
        stdcall xfs._.long_btree.seek, [_ptr+4], [_size]
1987
        stdcall xfs._.long_btree.seek, [_ptr+4], [_size]
1977
        mov     [_is_root], 0
1988
        mov     [_is_root], 0
1978
.begin:
1989
.begin:
1979
        mov     ebx, [ebp+XFS.cur_block]
1990
        mov     ebx, [ebp+XFS.cur_block]
1980
        mov     eax, [ebp+XFS.bmap_magic]
1991
        mov     eax, [ebp+XFS.bmap_magic]
1981
        cmp     [ebx+xfs_bmbt_block.bb_magic], eax
1992
        cmp     [ebx+xfs_bmbt_block.bb_magic], eax
1982
        movi    eax, ERROR_FS_FAIL
1993
        movi    eax, ERROR_FS_FAIL
1983
        jnz     .error
1994
        jnz     .error
1984
        movzx   ecx, [ebx+xfs_bmbt_block.bb_numrecs]
1995
        movzx   ecx, [ebx+xfs_bmbt_block.bb_numrecs]
1985
        xchg    cl, ch
1996
        xchg    cl, ch
1986
        add     ebx, [ebp+XFS.bmbt_block_size]
1997
        add     ebx, [ebp+XFS.bmbt_block_size]
1987
        stdcall xfs._.walk_extent_list, ecx, ebx, [_callback_extent+8], [_callback_block+4], [_callback_data]
1998
        stdcall xfs._.walk_extent_list, ecx, ebx, [_callback_extent+8], [_callback_block+4], [_callback_data]
1988
        jnz     .error
1999
        jnz     .error
1989
        mov     esi, [ebp+XFS.offset_begin.lo]
2000
        mov     esi, [ebp+XFS.offset_begin.lo]
1990
        mov     edi, [ebp+XFS.offset_begin.hi]
2001
        mov     edi, [ebp+XFS.offset_begin.hi]
1991
        cmp     edi, [ebp+XFS.offset_end.hi]
2002
        cmp     edi, [ebp+XFS.offset_end.hi]
1992
        ja      .quit
2003
        ja      .quit
1993
        cmp     esi, [ebp+XFS.offset_end.lo]
2004
        cmp     esi, [ebp+XFS.offset_end.lo]
1994
        jae     .quit
2005
        jae     .quit
1995
        sub     ebx, [ebp+XFS.bmbt_block_size]
2006
        sub     ebx, [ebp+XFS.bmbt_block_size]
1996
        movbe   edx, [ebx+xfs_bmbt_block.bb_rightsib.lo]
2007
        movbe   edx, [ebx+xfs_bmbt_block.bb_rightsib.lo]
1997
        movbe   eax, [ebx+xfs_bmbt_block.bb_rightsib.hi]
2008
        movbe   eax, [ebx+xfs_bmbt_block.bb_rightsib.hi]
1998
        mov     ecx, eax
2009
        mov     ecx, eax
1999
        and     ecx, edx
2010
        and     ecx, edx
2000
        inc     ecx
2011
        inc     ecx
2001
        jz      .quit
2012
        jz      .quit
2002
        mov     ebx, [ebp+XFS.cur_block]
2013
        mov     ebx, [ebp+XFS.cur_block]
2003
        stdcall xfs._.read_block
2014
        stdcall xfs._.read_block
2004
        jnz     .error
2015
        jnz     .error
2005
        jmp     .begin
2016
        jmp     .begin
2006
.error:
2017
.error:
2007
.quit:
2018
.quit:
2008
        ret
2019
        ret
2009
endp
2020
endp
2010
 
2021
 
2011
 
2022
 
2012
proc xfs._.btree_read_block uses ebx esi edi, _tree, _size, _block_lo, _block_hi, _buf
2023
proc xfs._.btree_read_block uses ebx esi edi, _tree, _size, _block_lo, _block_hi, _buf
2013
        mov     eax, [_block_lo]
2024
        mov     eax, [_block_lo]
2014
        mov     [ebp+XFS.offset_begin.lo], eax
2025
        mov     [ebp+XFS.offset_begin.lo], eax
2015
        mov     eax, [_block_hi]
2026
        mov     eax, [_block_hi]
2016
        mov     [ebp+XFS.offset_begin.hi], eax
2027
        mov     [ebp+XFS.offset_begin.hi], eax
2017
        stdcall xfs._.long_btree.seek, [_tree+4], [_size]
2028
        stdcall xfs._.long_btree.seek, [_tree+4], [_size]
2018
        jnz     .error
2029
        jnz     .error
2019
        mov     ebx, [ebp+XFS.cur_block]
2030
        mov     ebx, [ebp+XFS.cur_block]
2020
        mov     eax, [ebp+XFS.bmap_magic]
2031
        mov     eax, [ebp+XFS.bmap_magic]
2021
        cmp     [ebx+xfs_bmbt_block.bb_magic], eax
2032
        cmp     [ebx+xfs_bmbt_block.bb_magic], eax
2022
        jnz     .error
2033
        jnz     .error
2023
        movzx   ecx, [ebx+xfs_bmbt_block.bb_numrecs]
2034
        movzx   ecx, [ebx+xfs_bmbt_block.bb_numrecs]
2024
        xchg    cl, ch
2035
        xchg    cl, ch
2025
        add     ebx, [ebp+XFS.bmbt_block_size]
2036
        add     ebx, [ebp+XFS.bmbt_block_size]
2026
        mov     eax, [_block_lo]
2037
        mov     eax, [_block_lo]
2027
        mov     [ebp+XFS.offset_begin.lo], eax
2038
        mov     [ebp+XFS.offset_begin.lo], eax
2028
        mov     eax, [_block_hi]
2039
        mov     eax, [_block_hi]
2029
        mov     [ebp+XFS.offset_begin.hi], eax
2040
        mov     [ebp+XFS.offset_begin.hi], eax
2030
        stdcall xfs._.extent_list.seek, ecx
2041
        stdcall xfs._.extent_list.seek, ecx
2031
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], [_buf]
2042
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], \
-
 
2043
                [ebp+XFS.extent.br_startblock.hi], [_buf]
2032
.error:
2044
.error:
2033
.quit:
2045
.quit:
2034
        ret
2046
        ret
2035
endp
2047
endp
2036
 
2048
 
2037
 
2049
 
2038
proc xfs._.extent_list.seek uses esi, _count
2050
proc xfs._.extent_list.seek uses esi, _count
2039
        sub     ebx, sizeof.xfs_bmbt_rec
2051
        sub     ebx, sizeof.xfs_bmbt_rec
2040
        inc     [_count]
2052
        inc     [_count]
2041
.find_low:
2053
.find_low:
2042
        add     ebx, sizeof.xfs_bmbt_rec
2054
        add     ebx, sizeof.xfs_bmbt_rec
2043
        dec     [_count]
2055
        dec     [_count]
2044
        jz      .quit
2056
        jz      .quit
2045
        stdcall xfs._.extent_unpack, ebx
2057
        stdcall xfs._.extent_unpack, ebx
2046
        mov     eax, [ebp+XFS.extent.br_startoff.lo]
2058
        mov     eax, [ebp+XFS.extent.br_startoff.lo]
2047
        mov     edx, [ebp+XFS.extent.br_startoff.hi]
2059
        mov     edx, [ebp+XFS.extent.br_startoff.hi]
2048
        mov     esi, [ebp+XFS.extent.br_blockcount]
2060
        mov     esi, [ebp+XFS.extent.br_blockcount]
2049
        add     eax, esi
2061
        add     eax, esi
2050
        adc     edx, 0
2062
        adc     edx, 0
2051
 
2063
 
2052
        cmp     edx, [ebp+XFS.offset_begin.hi]
2064
        cmp     edx, [ebp+XFS.offset_begin.hi]
2053
        ja      .low_found
2065
        ja      .low_found
2054
        jb      .find_low
2066
        jb      .find_low
2055
        cmp     eax, [ebp+XFS.offset_begin.lo]
2067
        cmp     eax, [ebp+XFS.offset_begin.lo]
2056
        ja      .low_found
2068
        ja      .low_found
2057
        jmp     .find_low
2069
        jmp     .find_low
2058
.low_found:
2070
.low_found:
2059
        add     ebx, sizeof.xfs_bmbt_rec
2071
        add     ebx, sizeof.xfs_bmbt_rec
2060
 
2072
 
2061
        mov     eax, [ebp+XFS.offset_begin.lo]
2073
        mov     eax, [ebp+XFS.offset_begin.lo]
2062
        mov     edx, [ebp+XFS.offset_begin.hi]
2074
        mov     edx, [ebp+XFS.offset_begin.hi]
2063
        mov     esi, eax
2075
        mov     esi, eax
2064
        sub     esi, [ebp+XFS.extent.br_startoff.lo]
2076
        sub     esi, [ebp+XFS.extent.br_startoff.lo]
2065
        jbe     .quit
2077
        jbe     .quit
2066
        ; same br_blockcount for block and dirblock?
2078
        ; same br_blockcount for block and dirblock?
2067
        mov     [ebp+XFS.extent.br_startoff.lo], eax
2079
        mov     [ebp+XFS.extent.br_startoff.lo], eax
2068
        mov     [ebp+XFS.extent.br_startoff.hi], edx
2080
        mov     [ebp+XFS.extent.br_startoff.hi], edx
2069
        sub     [ebp+XFS.extent.br_blockcount], esi
2081
        sub     [ebp+XFS.extent.br_blockcount], esi
2070
        add     [ebp+XFS.extent.br_startblock.lo], esi
2082
        add     [ebp+XFS.extent.br_startblock.lo], esi
2071
        adc     [ebp+XFS.extent.br_startblock.hi], 0
2083
        adc     [ebp+XFS.extent.br_startblock.hi], 0
2072
        jmp     .quit
2084
        jmp     .quit
2073
.quit:
2085
.quit:
2074
        mov     eax, [_count]
2086
        mov     eax, [_count]
2075
        ret
2087
        ret
2076
endp
2088
endp
2077
 
2089
 
2078
 
2090
 
2079
proc xfs._.extent_iterate_dirblocks _callback, _callback_data
2091
proc xfs._.extent_iterate_dirblocks _callback, _callback_data
2080
.check_high:
2092
.check_high:
2081
        cmp     edi, [ebp+XFS.offset_end.hi]
2093
        cmp     edi, [ebp+XFS.offset_end.hi]
2082
        ja      .quit
2094
        ja      .quit
2083
        jb      .read_dirblock
2095
        jb      .read_dirblock
2084
        cmp     esi, [ebp+XFS.offset_end.lo]
2096
        cmp     esi, [ebp+XFS.offset_end.lo]
2085
        jae     .quit
2097
        jae     .quit
2086
.read_dirblock:
2098
.read_dirblock:
2087
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], [ebp+XFS.cur_dirblock]
2099
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], [ebp+XFS.cur_dirblock]
2088
        mov     edx, [ebp+XFS.cur_dirblock]
2100
        mov     edx, [ebp+XFS.cur_dirblock]
2089
        mov     eax, [_callback]
2101
        mov     eax, [_callback]
2090
        stdcall eax, edx, esi, edi, [_callback_data]
2102
        stdcall eax, edx, esi, edi, [_callback_data]
2091
        test    eax, eax
2103
        test    eax, eax
2092
        jnz     .error
2104
        jnz     .error
2093
        mov     eax, [ebp+XFS.blkpdirblk]
2105
        mov     eax, [ebp+XFS.blkpdirblk]
2094
        add     esi, eax
2106
        add     esi, eax
2095
        adc     edi, 0
2107
        adc     edi, 0
2096
        add     [ebp+XFS.extent.br_startblock.lo], eax
2108
        add     [ebp+XFS.extent.br_startblock.lo], eax
2097
        adc     [ebp+XFS.extent.br_startblock.hi], 0
2109
        adc     [ebp+XFS.extent.br_startblock.hi], 0
2098
        sub     [ebp+XFS.extent.br_blockcount], eax
2110
        sub     [ebp+XFS.extent.br_blockcount], eax
2099
        jnz     .check_high
2111
        jnz     .check_high
2100
.error:
2112
.error:
2101
.quit:
2113
.quit:
2102
        ret
2114
        ret
2103
endp
2115
endp
2104
 
2116
 
2105
 
2117
 
2106
proc xfs._.walk_extent_list uses ebx esi edi, _count, _ptr, _callback_extent, _callback_block, _callback_data
2118
proc xfs._.walk_extent_list uses ebx esi edi, _count, _ptr, _callback_extent, _callback_block, _callback_data
2107
        mov     ebx, [_ptr]
2119
        mov     ebx, [_ptr]
2108
        stdcall xfs._.extent_list.seek, [_count]
2120
        stdcall xfs._.extent_list.seek, [_count]
2109
        mov     [_count], eax
2121
        mov     [_count], eax
2110
        dec     [_count]
2122
        dec     [_count]
2111
        js      .quit
2123
        js      .quit
2112
        jmp     .next_extent.decoded
2124
        jmp     .next_extent.decoded
2113
.next_extent:
2125
.next_extent:
2114
        stdcall xfs._.extent_unpack, ebx
2126
        stdcall xfs._.extent_unpack, ebx
2115
        add     ebx, sizeof.xfs_bmbt_rec
2127
        add     ebx, sizeof.xfs_bmbt_rec
2116
.next_extent.decoded:
2128
.next_extent.decoded:
2117
        mov     eax, [ebp+XFS.extent.br_blockcount]
2129
        mov     eax, [ebp+XFS.extent.br_blockcount]
2118
        add     [ebp+XFS.offset_begin.lo], eax
2130
        add     [ebp+XFS.offset_begin.lo], eax
2119
        adc     [ebp+XFS.offset_begin.hi], 0
2131
        adc     [ebp+XFS.offset_begin.hi], 0
2120
        mov     esi, [ebp+XFS.extent.br_startoff.lo]
2132
        mov     esi, [ebp+XFS.extent.br_startoff.lo]
2121
        mov     edi, [ebp+XFS.extent.br_startoff.hi]
2133
        mov     edi, [ebp+XFS.extent.br_startoff.hi]
2122
        stdcall [_callback_extent+8], [_callback_block+4], [_callback_data]
2134
        stdcall [_callback_extent+8], [_callback_block+4], [_callback_data]
2123
        jnz     .error
2135
        jnz     .error
2124
        cmp     edi, [ebp+XFS.offset_end.hi]
2136
        cmp     edi, [ebp+XFS.offset_end.hi]
2125
        ja      .quit
2137
        ja      .quit
2126
        jb      @f
2138
        jb      @f
2127
        cmp     esi, [ebp+XFS.offset_end.lo]
2139
        cmp     esi, [ebp+XFS.offset_end.lo]
2128
        jae     .quit
2140
        jae     .quit
2129
@@:
2141
@@:
2130
        dec     [_count]
2142
        dec     [_count]
2131
        js      .quit
2143
        js      .quit
2132
        jmp     .next_extent
2144
        jmp     .next_extent
2133
.quit:
2145
.quit:
2134
        movi    eax, ERROR_SUCCESS
2146
        movi    eax, ERROR_SUCCESS
2135
.error:
2147
.error:
2136
        test    eax, eax
2148
        test    eax, eax
2137
        ret
2149
        ret
2138
endp
2150
endp
2139
 
2151
 
2140
 
2152
 
2141
proc xfs._.get_last_dirblock uses ecx
2153
proc xfs._.get_last_dirblock uses ecx
2142
        mov     eax, [ebp+XFS.nextents_offset]
2154
        mov     eax, [ebp+XFS.nextents_offset]
2143
        movbe   eax, [ebx+eax]
2155
        movbe   eax, [ebx+eax]
2144
assert (sizeof.xfs_bmbt_rec AND (sizeof.xfs_bmbt_rec - 1)) = 0
2156
assert (sizeof.xfs_bmbt_rec AND (sizeof.xfs_bmbt_rec - 1)) = 0
2145
        shl     eax, BSF sizeof.xfs_bmbt_rec
2157
        shl     eax, BSF sizeof.xfs_bmbt_rec
2146
        add     eax, [ebp+XFS.inode_core_size]
2158
        add     eax, [ebp+XFS.inode_core_size]
2147
        lea     eax, [ebx+eax-sizeof.xfs_bmbt_rec]
2159
        lea     eax, [ebx+eax-sizeof.xfs_bmbt_rec]
2148
        stdcall xfs._.extent_unpack, eax
2160
        stdcall xfs._.extent_unpack, eax
2149
        xor     edx, edx
2161
        xor     edx, edx
2150
        mov     eax, [ebp+XFS.extent.br_blockcount]
2162
        mov     eax, [ebp+XFS.extent.br_blockcount]
2151
        mov     ecx, [ebp+XFS.dirblklog]
2163
        mov     ecx, [ebp+XFS.dirblklog]
2152
        shr     eax, cl
2164
        shr     eax, cl
2153
        dec     eax
2165
        dec     eax
2154
        add     eax, [ebp+XFS.extent.br_startoff.lo]
2166
        add     eax, [ebp+XFS.extent.br_startoff.lo]
2155
        adc     edx, [ebp+XFS.extent.br_startoff.hi]
2167
        adc     edx, [ebp+XFS.extent.br_startoff.hi]
2156
        ret
2168
        ret
2157
endp
2169
endp
2158
 
2170
 
2159
 
2171
 
2160
restore prologue@proc,epilogue@proc
2172
restore prologue@proc,epilogue@proc
2161
restore movbe
2173
restore movbe