]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/MAPPER/F_NEXT.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / MAPPER / F_NEXT.ASM
1 ;
2 page 80,132
3 ;
4 title CP/DOS DosFindNext mapper
5 ;
6
7 include find.inc
8
9 FindSegment segment word public 'find'
10
11 extrn SearchCount:word
12 extrn ReturnBufferSave:dword
13 extrn CurrentDTA:word
14 extrn ReturnLengthToGo:word
15
16 extrn SaveDTA:dword
17 extrn SaveDTAOffset:word
18 extrn SaveDTASegment:word
19 extrn SaveDTAFlag:byte
20
21 ; We will use the offset into the segment 'FindSegment' as the handle that we
22 ; return and use in subsequent FindNext and FindClose calls. The data that is
23 ; in the word is the offset into the 'FindSegment' to the DTA that we should
24 ; use.
25
26 extrn FindDTAs:word
27
28 extrn FindHandles:word
29
30 FindSegment ends
31
32 dosxxx segment byte public 'dos'
33 assume cs:dosxxx,ds:nothing,es:nothing,ss:nothing
34 ;
35 ; ************************************************************************* *
36 ; *
37 ; * MODULE: DosFindNext
38 ; *
39 ; * FILE NAME: DOS022.ASM
40 ; *
41 ; * FUNCTION: This module finds the next file in a sequence initiated
42 ; * by the find first the command.
43 ; *
44 ; *
45 ; *
46 ; *
47 ; * CALLING SEQUENCE:
48 ; *
49 ; * PUSH WORD DirHandle ; Directory search handle
50 ; * PUSH@ OTHER ResultBuf ; Result buffer
51 ; * PUSH DWORD ResultBufLen ; Result buffer length
52 ; * PUSH@ WORD SearchCount ; # of entries to find
53 ; * CALL DosFindNext
54 ; *
55 ; *
56 ; * RETURN SEQUENCE:
57 ; *
58 ; * IF ERROR (AX not = 0)
59 ; *
60 ; * AX = Error Code:
61 ; *
62 ; * o Invalid file path name
63 ; *
64 ; * o Invalid search attribute
65 ; *
66 ; * MODULES CALLED: DOS int 21H function 2FH
67 ; * DOS int 21H function 4FH
68 ; *
69 ; *************************************************************************
70 ;
71 public DosFindNext
72 .sall
73 .xlist
74 include macros.inc
75 .list
76 ;
77
78 str struc
79 old_bp dw ?
80 return dd ?
81 FindCountPtr dd ?
82 FindBufferLen dw ?
83 FindBufferPtr dd ? ;Changed to DW to match the DOSCALL.h PyL 6/1 Rsltbuf21 dd ?
84 DirHandle dw ?
85 str ends
86
87 ;
88 DosFindNext proc far
89
90
91 Enter DosFindNext
92
93 mov ax,seg FindSegment ; get address to our data
94 mov ds,ax
95 assume ds:FindSegment
96
97 ; check for a valid dir handle
98
99 ; Special Logic to handle DirHandle = 1
100
101 mov si,[bp].DirHandle
102 cmp si,1
103 jne CheckForNext
104
105 mov si,offset FindSegment:FindHandles
106
107 CheckForNext:
108 test ds:[si],OpenedHandle
109 jnz OkToFindNext
110
111 mov ax,6
112 jmp ErrorExit
113
114 OkToFindNext:
115
116 ; We have a handle, let's look for the file(s)
117
118 HandleFound:
119 mov si,ds:[si] ; get the DTA pointer
120 and si,not OpenedHandle ; and get rid of the allocated flag
121 mov CurrentDTA,si ; and save the current DTA value
122
123 ; save the callers dta so we can restore it later
124
125 mov ah,02fh
126 int 21h
127 mov SaveDTAOffset,bx
128 mov SaveDTASegment,es
129 mov SaveDTAFlag,1
130
131 ; Set the dta to our area
132
133 mov dx,CurrentDTA
134 mov ah,1ah
135 int 21h
136
137 ; Get the count of files to search for
138
139 les di,[bp].FindCountPtr ; load result buffer pointer
140 mov ax,es:[di] ; save the search
141 mov SearchCount,ax ; count
142 mov es:word ptr [di],0 ; set found count to zero
143
144 cmp ax,0 ; just in case they try to trick us!
145 jne DoSearch
146
147 jmp SearchDone
148
149 ; Find first file
150
151 DoSearch:
152 mov ax,[bp].FindBufferLen ; load the buffer length
153 mov ReturnLengthToGo,ax ; save low order buffer length
154
155 les di,[bp].FindBufferPtr ; load result buffer pointer
156 mov word ptr ReturnBufferSave+0,di
157 mov word ptr ReturnBufferSave+2,es
158
159 DoFindNext:
160 mov ax,4f00h
161 int 21h
162 jnc MoveFindData
163
164 jmp ErrorExit
165
166 ; Move find data into the return areas
167
168 MoveFindData:
169 sub ReturnLengthToGo,size FileFindBuf ; check if result buffer is larg enough
170 jnc BufferLengthOk ; it is ok
171
172 mov ax,8 ; report 'Insufficient memory'
173 jmp ErrorExit ; error return - buffer not large enough
174
175 BufferLengthOk:
176 mov si,CurrentDTA ; DS:SI -> our dta area
177 les di,ReturnBufferSave
178
179 ; At this point, the following MUST be true:
180 ; es:di -> where we are to put the resultant data
181 ; ds:si -> DTA from find (either first or next)
182
183 mov ax,ds:[si].DTAFileDate
184 mov es:[di].Create_Date,ax
185 mov es:[di].Access_Date,ax
186 mov es:[di].Write_Date,ax
187
188 mov ax,ds:[si].DTAFileTime
189 mov es:[di].Create_Time,ax
190 mov es:[di].Access_Time,ax
191 mov es:[di].Write_Time,ax
192
193 mov ax,ds:word ptr [si].DTAFileSize+0
194 mov es:word ptr [di].File_Size+0,ax
195 mov es:word ptr [di].FAlloc_Size+0,ax
196 mov ax,ds:word ptr [si].DTAFileSize+2
197 mov es:word ptr [di].File_Size+2,ax
198 mov es:word ptr [di].FAlloc_Size+2,ax
199
200 test es:word ptr [di].FAlloc_Size,001ffh
201 jz AllocateSizeSet
202
203 and es:word ptr [di].FAlloc_Size,not 001ffh
204 add es:word ptr [di].FAlloc_Size,00200h
205
206 AllocateSizeSet:
207 xor ax,ax
208 mov al,ds:[si].DTAFileAttrib
209 mov es:[di].Attributes,ax
210
211 mov cx,12
212 mov bx,0
213
214 MoveNameLoop:
215 mov al,ds:[si+bx].DTAFileName
216 cmp al,0
217 je EndOfName
218
219 mov es:[di+bx].File_Name,al
220 inc bx
221 loop MoveNameLoop
222
223 EndOfName:
224 mov es:[di+bx].File_Name,0
225 mov ax,bx
226 mov es:[di].String_len,al
227
228 add di,bx
229 mov word ptr ReturnBufferSave+0,di
230 mov word ptr ReturnBufferSave+2,es
231
232 les di,[bp].FindCountPtr
233 inc word ptr es:[di]
234
235 ;
236 ; Check if the request was for more than one
237 ;
238 dec SearchCount
239 jz SearchDone
240
241 jmp DoFindNext
242
243 SearchDone:
244 sub ax,ax ; set good return code
245
246 ErrorExit:
247 push ax
248 mov ax,seg FindSegment
249 mov ds,ax
250 assume ds:FindSegment
251 cmp SaveDTAFlag,0
252 je DoNotRestore
253
254 mov SaveDTAFlag,0
255
256 lds dx,SaveDTA
257 mov ah,1ah
258 int 21h
259
260 DoNotRestore:
261 pop ax
262
263 mexit
264
265 ret size str - 6
266
267 DosFindNext endp
268
269 dosxxx ends
270
271 end