1 ; SCCSID = @(#)path.asm 1.1 85/04/10
2 TITLE PATH
- Directory related system calls
6 ; Directory related system calls. These will be passed direct text of the
7 ; pathname from the user. They will need to be passed through the macro
8 ; expander prior to being sent through the low-level stuff. I/O specs are
9 ; defined in DISPATCH. The system calls are:
11 ; $CURRENT_DIR Written
17 ; Modification history:
19 ; Created: ARR 4 April 1983
20 ; MZ 10 May 1983 CurrentDir implemented
21 ; MZ 11 May 1983 RmDir, ChDir, MkDir implemented
22 ; EE 19 Oct 1983 RmDir no longer allows you to delete a
24 ; MZ 19 Jan 1983 Brain damaged applications rely on success
28 ; get the appropriate segment definitions
32 CODE SEGMENT BYTE PUBLIC 'CODE'
33 ASSUME
SS:DOSGroup
,CS:DOSGroup
41 EXTRN DOS_MkDir
:NEAR,DOS_RmDir
:NEAR
43 I_Need ThisCDS
,DWORD ; pointer to Current CDS
44 I_Need WFP_Start
,WORD ; pointer to beginning of directory text
45 I_Need Curr_Dir_End
,WORD ; offset to end of directory part
46 I_Need OpenBuf
,128 ; temp spot for translated name
47 I_need fSplice
,BYTE ; TRUE => do splice
48 I_Need NoSetDir
,BYTE ; TRUE => no exact match on splice
50 I_Need DrvErr
,BYTE ;AN000;
52 BREAK <$CURRENT_DIR
- dump the current directory
into user space
>
58 ; ; DS:SI is a pointer to 64 byte area that contains drive
59 ; ; current directory.
61 ; AX = error_invalid_drive
64 procedure $CURRENT_DIR
,NEAR
65 ASSUME
CS:DOSGroup
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
67 MOV AL,DL ; get drive number (0=def, 1=A)
68 Invoke GetVisDrv
; grab it
69 JNC CurrentValidate
; no error -> go and validate dir
72 MOV AL,[DrvErr
] ;IFS. ;AN000;
73 transfer SYS_RET_ERR
;IFS. make noise ;AN000;
75 SaveReg
<DS,SI> ; save destination
77 TEST [SI].curdir_flags
,curdir_isnet
79 ; Random optimization nuked due to some utilities using GetCurrentDir to do
81 ; CMP [SI].curdir_id,0
84 MOV NoSetDir
,0 ; interested only in contents
85 MOV DI,OFFSET DOSGroup
:OpenBuf
86 Invoke ValidateCDS
; output is ES:DI -> CDS
87 SaveReg
<ES,DI> ; swap source and destination
90 RestoreReg
<DI,ES> ; get real destination
93 ADD SI,[SI.curdir_END
]
94 CMP BYTE PTR [SI],'\' ; root or subdirs present?
110 CMP AL,'\' ; beginning of directory
112 STOSB ; put into user's buffer
113 LODSB ; 1st char of dir is 05?
117 MOV AL,0E5H ; make it E5
119 STOSB ; put into user's buffer
120 OR AL,AL ; final char
125 xor AL,AL ; MZ 19 Jan 84
127 transfer Sys_Ret_OK
; no more, bye!
130 BREAK <$RmDir
-- Remove a directory
>
133 ; DS:DX Points to asciz name
135 ; Delete directory if empty
138 ; AX = error_path_not_found If path bad
139 ; AX = error_access_denied If
140 ; Directory not empty
142 ; Root directory specified
143 ; Directory malformed (. and .. not first two entries)
144 ; User tries to delete a current directory
145 ; AX = error_current_directory
147 procedure $RMDIR
,NEAR
148 ASSUME
CS:DOSGroup
,DS:NOTHING
,ES:NOTHING
,SS:DOSGroup
150 push dx ; Save ptr to name
152 mov si,dx ; Load ptr into si
153 mov di,offset DOSGroup
:OpenBuf
; di = ptr to buf for trans name
155 Invoke TransPathNoSet
; Translate the name
156 pop di ; di = ptr to buf for trans name
157 jnc rmlset
; If transpath succeeded, continue
159 pop dx ; Restore the name
160 error error_path_not_found
; Otherwise, return an error
163 CMP cMeta
,-1 ; if (cMeta >= 0)
164 Jnz rmerr
; return (-1);
166 xor al,al ; al = 0 , ie drive a:
167 rmloop: Invoke GetCDSFromDrv
; Get curdir for drive in al
168 jc rmcont
; If error, exit loop & cont normally
169 Invoke StrCmp
; Are the 2 paths the same?
170 jz rmerr
; Yes, report error.
171 inc al ; No, inc al to next drive number
172 jmp rmloop
; Go check next drive.
176 pop dx ; Restore the name
177 error error_current_directory
; error
181 pop dx ; Restore the name
182 MOV SI,OFFSET DOSGroup
:DOS_RmDIR
186 BREAK <$ChDir
-- Change current directory
on a drive
>
189 ; $ChDir - Top-level change directory system call. This call is responsible
190 ; for setting up the CDS for the specified drive appropriately. There are
191 ; several cases to consider:
193 ; o Local, simple CDS. In this case, we take the input path and convert
194 ; it into a WFP. We verify the existance of this directory and then
195 ; copy the WFP into the CDS and set up the ID field to point to the
197 ; o Net CDS. We form the path from the root (including network prefix)
198 ; and verify its existance (via DOS_Chdir). If successful, we copy the
199 ; WFP back into the CDS.
200 ; o SUBST'ed CDS. This is no different than the local, simple CDS.
201 ; o JOIN'ed CDS. This is trouble as there are two CDS's at work. If we
202 ; call TransPath, we will get the PHYSICAL CDS that the path refers to
203 ; and the PHYSICAL WFP that the input path refers to. This is perfectly
204 ; good for the validation but not for currency. We call TransPathNoSet
205 ; to process the path but to return the logical CDS and the logical
206 ; path. We then copy the logical path into the logical CDS.
209 ; DS:DX Points to asciz name
212 ; AX = chdir_path_not_found if error
214 procedure $CHDIR
,NEAR
215 ASSUME
CS:DOSGroup
,DS:NOTHING
,ES:NOTHING
,SS:DOSGroup
216 MOV DI,OFFSET DOSGroup
:OpenBuf
; spot for translated name
217 MOV SI,DX ; get source
218 Invoke TransPath
; go munge the path and get real CDS
219 JNC ChDirCrack
; no errors, try path
221 MOV AL,error_path_not_found
223 transfer SYS_Ret_Err
; oops!
227 CMP cMeta
,-1 ; No meta chars allowed.
230 ; We cannot do a ChDir (yet) on a raw CDS. This is treated as a path not
234 CMP DI,-1 ; if (ThisCDS == NULL)
235 JZ ChDirErrP
; error ();
237 ; Find out if the directory exists.
242 ; Get back CDS to see if a join as seen. Set the currency pointer (only if
243 ; not network). If one was seen, all we need to do is copy in the text
246 TEST ES:[DI].curdir_flags
,curdir_splice
249 ; The CDS was joined. Let's go back and grab the logical CDS.
251 SaveReg
<ES,DI,CX> ; save CDS and cluster...
252 Invoke Get_User_Stack
; get original text
256 MOV SI,OFFSET DOSGroup
:OpenBuf
; spot for translated name
258 XOR AL,AL ; do no splicing
260 Invoke TransPathNoSet
; Munge path
264 ; There should NEVER be an error here.
268 fmt
<>,<>,<"$p: Internal CHDIR error\n">
271 LES DI,ThisCDS
; get new CDS
272 MOV ES:[DI].curdir_ID
,-1 ; no valid cluster here...
273 RestoreReg
<CX,DI,ES>
275 ; ES:DI point to the physical CDS, CX is the ID (local only)
279 ; wfp_start points to the text. See if it is long enough
281 CALL Check_PathLen
;PTM. ;AN000;
283 TEST ES:[DI].curdir_flags
,curdir_isnet
285 TEST ES:[DI].curdir_flags
,curdir_splice
;PTM. for Join and Subst ;AN000;
286 JZ setdirclus
;PTM. ;AN000;
287 MOV CX,-1 ;PTM. ;AN000;
289 MOV ES:[DI].curdir_id
,CX
290 LES DI,ThisCDS
; get logical CDS
297 BREAK <$MkDir
- Make a directory
entry>
299 ; DS:DX Points to asciz name
301 ; Make a new directory
304 ; AX = mkdir_path_not_found if path bad
305 ; AX = mkdir_access_denied If
306 ; Directory cannot be created
307 ; Node already exists
309 ; Disk or directory(root) full
311 procedure $MKDIR
,NEAR
312 ASSUME
CS:DOSGroup
,DS:NOTHING
,ES:NOTHING
,SS:DOSGroup
313 MOV SI,OFFSET DOSGroup
:DOS_MkDir
315 MOV DI,OFFSET DOSGroup
:OpenBuf
; spot for translated name
317 MOV SI,DX ; get source
318 Invoke TransPath
; go munge the path
320 JNC MkDirCrack
; no errors, try path
322 MOV AL,error_Path_Not_Found
; oops!
329 PUSH SI ;PTM. ;AN000;
330 CALL Check_PathLen
;PTM. check path len > 67 ? ;AN000;
332 JBE pathok
;PTM. ;AN000;
333 MOV AL,error_Access_Denied
;PTM. ops!
334 transfer Sys_Ret_Err
;PTM.
336 CALL SI ; go get file
345 ; check if final path length greater than 67
347 ; Above flag set if > 67
349 procedure Check_PathLen
,NEAR
350 ASSUME
CS:DOSGroup
,DS:NOTHING
,ES:NOTHING
,SS:DOSGroup
360 EndProc Check_PathLen