]>
wirehaze git hosting - MS-DOS.git/blob - v4.0/src/MAPPER/F_FIRST.ASM
3 title CP
/DOS DosFindFirst mapper
8 FindSegment
segment word public 'find'
12 public ReturnBufferSave
16 public ReturnLengthToGo
26 SaveDTAFlag db 0 ; 0 -> not saved
29 ; We will use the offset into the segment 'FindSegment' as the handle that we
30 ; return and use in subsequent FindNext and FindClose calls. The data that is
31 ; in the word is the offset into the 'FindSegment' to the DTA that we should
41 FindHandles
label word
44 dw FindDTAs
+ FindDTAIndex
45 FindDTAIndex
= FindDTAIndex
+ size dtastr
51 dosxxx
segment byte public 'dos'
52 assume
cs:dosxxx
,ds:nothing
,es:nothing
,ss:nothing
54 ; ************************************************************************* *
56 ; * MODULE: DosFindFirst
58 ; * FILE NAME: DOS021.ASM
60 ; * FUNCTION: This module Finds the first filename that matches the
61 ; * specified file specification. The directory handle
62 ; * parameter passed will be ignored since PC/DOS does not
63 ; * support directory handles. The last access, last write
64 ; * and the creation date and time are all set to the same,
65 ; * because PC/DOS does not have seperate last access and
66 ; * last write fields in the directory. The allocation
67 ; * fields are set equal to the eod because of the same
72 ; * PUSH@ ASCIIZ FileName ; File path name
73 ; * PUSH@ WORD DirHandle ; Directory search handle
74 ; * PUSH WORD Attribute ; Search attribute
75 ; * PUSH@ OTHER ResultBuf ; Result buffer
76 ; * PUSH DWORD ResultBufLen ; Result buffer length
77 ; * PUSH@ WORD SearchCount ; # of entries to find
78 ; * PUSH DWORD 0 ; Reserved (must be zero)
83 ; * IF ERROR (AX not = 0)
87 ; * o Invalid file path name
89 ; * o Invalid search attribute
91 ; * MODULES CALLED: DOS int 21H function 2FH
92 ; * DOS int 21H function 4EH
93 ; * DOS int 21H function 4FH
95 ; *************************************************************************
107 ReservedZero dd 0 ; reserved
108 FindCountPtr dd ?
; number of entries to find
109 FindBufferLen dw ?
; result buffer lenght
110 FindBufferPtr dd ?
; result buffer pointer
111 FileAttribute dw ?
; search attribute
112 DirHandlePtr dd ?
; directory search handle
113 PathNamePtr dd ?
; file path name pointer
117 DosFindFirst proc
far
121 mov ax,seg FindSegment
; get address to our data
123 assume
ds:FindSegment
125 ; Search for an available Find Handle
127 ; The Dir handle that we will return is the offset into the 'FindSegment' that
128 ; the pointer to the DTA for that handle is at. Two special things:
130 ; 1) when we see file handle one, will use the first pointer and DTA
131 ; 2) the high order bit of the DTA pointer is used to indicate that
132 ; the handle is allocated
134 mov si,offset FindSegment
:FindHandles
137 ; DS:[SI] -> Find DTA Pointer Table
138 ; CX = number of Find DTAs
140 ; Incoming DirHandle = -1 ==> allocate a new dir handle
142 les di,[bp].DirHandlePtr
147 ; Incoming DirHandle = 1, we will use the first DTA
152 ; We have not been requested to allocate a new handle, and we are not using
153 ; DirHandle 1. At this time, we need to reuse the incoming handle, but only
154 ; if it is a valid (ie - previously allocated by us) DirHandle
156 mov si,ax ; verify it is an active handle
157 test ds:[si],OpenedHandle
158 jnz HandleFound
; jump if true
160 mov ax,6 ; else set error code
161 jmp ErrorExit
; return
163 ; Allocate a new handle from the DTA pointer list
170 test ds:[si],OpenedHandle
176 ; No Handles available, return error
178 mov ax,4 ; report 'no handles available'
179 jmp ErrorExit
; error return - buffer not large enough
182 ; We have a handle, let's look for the file(s)
185 mov ax,ds:[si] ; get the dta pointer
186 or ds:[si],OpenedHandle
; allocate the handle
187 and ax,not OpenedHandle
190 les di,[bp].DirHandlePtr
; the handle number we return is the
191 mov es:[di],si ; offset to the entry in FindSegment
193 ; save the callers dta so we can restore it later
195 mov ah,02fh ; get callers DTA
198 mov SaveDTAOffset
,bx ; save it
199 mov SaveDTASegment
,es
202 ; Set the dta to our area
204 mov dx,CurrentDTA
; set DTA address
208 ; Get the count of files to search for
210 les di,[bp].FindCountPtr
; load result buffer pointer
211 mov ax,es:[di] ; save the search
212 mov SearchCount
,ax ; count
213 mov es:word ptr [di],0 ; set found count to zero
215 cmp ax,0 ; just in case they try to trick us!
223 lds dx,[bp].PathNamePtr
; load address of asciiz string
225 mov cx,[bp].FileAttribute
; load the attribute
227 int 21h
; find the first occurance of file
228 jnc FindFirstOK
; continue
233 mov ax,seg FindSegment
235 assume
ds:FindSegment
237 mov ax,[bp].FindBufferLen
; load the buffer length
238 mov ReturnLengthToGo
,ax ; save low order buffer length
240 les di,[bp].FindBufferPtr
; load result buffer pointer
242 mov word ptr ReturnBufferSave
+0,di
243 mov word ptr ReturnBufferSave
+2,es
245 ; Move find data into the return areas
248 sub ReturnLengthToGo
,size FileFindBuf
; check if result buffer is larg enough
249 jnc BufferLengthOk
; it is ok
251 mov ax,8 ; report 'Insufficient memory'
252 jmp ErrorExit
; error return - buffer not large enough
255 mov si,CurrentDTA
; DS:SI -> our dta area
256 les di,ReturnBufferSave
258 ; At this point, the following MUST be true:
259 ; es:di -> where we are to put the resultant data
260 ; ds:si -> DTA from find (either first or next)
262 mov ax,ds:[si].DTAFileDate
; save date
263 mov es:[di].Create_Date
,ax
264 mov es:[di].Access_Date
,ax
265 mov es:[di].Write_Date
,ax
267 mov ax,ds:[si].DTAFileTime
; save time
268 mov es:[di].Create_Time
,ax
269 mov es:[di].Access_Time
,ax
270 mov es:[di].Write_Time
,ax
272 mov ax,ds:word ptr [si].DTAFileSize
+0 ; save file size
273 mov es:word ptr [di].File_Size
+0,ax
274 mov es:word ptr [di].FAlloc_Size
+0,ax
275 mov ax,ds:word ptr [si].DTAFileSize
+2
276 mov es:word ptr [di].File_Size
+2,ax
277 mov es:word ptr [di].FAlloc_Size
+2,ax
279 test es:word ptr [di].FAlloc_Size
,001ffh
282 and es:word ptr [di].FAlloc_Size
,not 001ffh
283 add es:word ptr [di].FAlloc_Size
,00200h
287 mov al,ds:[si].DTAFileAttrib
288 mov es:[di].Attributes
,ax
294 mov al,ds:[si+bx].DTAFileName
298 mov es:[di+bx].File_Name
,al
303 mov es:[di+bx].File_Name
,0
305 mov es:[di].String_len
,al
308 mov word ptr ReturnBufferSave
+0,di
309 mov word ptr ReturnBufferSave
+2,es
311 les di,[bp].FindCountPtr
315 ; Check if the request was for more than one
320 mov ax,04f00h ; set opcode
321 int 21h
; find next matching file
322 jc ErrorExit
; jump if error
324 les di,ReturnBufferSave
;
328 sub ax,ax ; set good return code
332 mov ax,seg FindSegment
334 assume
ds:FindSegment
341 mov ah,1
ah ; load opcode
347 mexit
; pop registers
348 ret size
str - 6 ; return