summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/PATH.ASM
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--v4.0/src/DOS/PATH.ASM363
1 files changed, 363 insertions, 0 deletions
diff --git a/v4.0/src/DOS/PATH.ASM b/v4.0/src/DOS/PATH.ASM
new file mode 100644
index 0000000..5deed6c
--- /dev/null
+++ b/v4.0/src/DOS/PATH.ASM
@@ -0,0 +1,363 @@
1; SCCSID = @(#)path.asm 1.1 85/04/10
2TITLE PATH - Directory related system calls
3NAME PATH
4
5;
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:
10;
11; $CURRENT_DIR Written
12; $RMDIR Written
13; $CHDIR Written
14; $MKDIR Written
15;
16;
17; Modification history:
18;
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
23; current directory.
24; MZ 19 Jan 1983 Brain damaged applications rely on success
25; values of AL.
26.xlist
27;
28; get the appropriate segment definitions
29;
30include dosseg.asm
31
32CODE SEGMENT BYTE PUBLIC 'CODE'
33 ASSUME SS:DOSGroup,CS:DOSGroup
34
35.xcref
36INCLUDE DOSSYM.INC
37INCLUDE DEVSYM.INC
38.cref
39.list
40
41 EXTRN DOS_MkDir:NEAR,DOS_RmDir:NEAR
42
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
49 I_Need cMeta,BYTE
50 I_Need DrvErr,BYTE ;AN000;
51
52BREAK <$CURRENT_DIR - dump the current directory into user space>
53;
54; Assembler usage:
55; LDS SI,area
56; MOV DL,drive
57; INT 21h
58; ; DS:SI is a pointer to 64 byte area that contains drive
59; ; current directory.
60; Error returns:
61; AX = error_invalid_drive
62;
63
64 procedure $CURRENT_DIR,NEAR
65 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING
66 EnterCrit critDisk
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
70CurdirErr:
71 LeaveCrit critDisk
72 MOV AL,[DrvErr] ;IFS. ;AN000;
73 transfer SYS_RET_ERR ;IFS. make noise ;AN000;
74CurrentValidate:
75 SaveReg <DS,SI> ; save destination
76 LDS SI,ThisCDS
77 TEST [SI].curdir_flags,curdir_isnet
78 JNZ DoCheck
79; Random optimization nuked due to some utilities using GetCurrentDir to do
80; media check.
81; CMP [SI].curdir_id,0
82; JZ GetDst
83DoCheck:
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
88 RestoreReg <SI,DS>
89GetDst:
90 RestoreReg <DI,ES> ; get real destination
91 JC CurdirErr
92 ADD SI,curdir_text
93 ADD SI,[SI.curdir_END]
94 CMP BYTE PTR [SI],'\' ; root or subdirs present?
95 JNZ CurrentCopy
96 INC SI
97CurrentCopy:
98; Invoke FStrCpy
99;; 10/29/86 E5 char
100 PUSH AX
101 LODSB ; get char
102 OR AL,AL
103 JZ FOK
104 CMP AL,05
105 JZ FCHANGE
106 JMP FFF
107FCPYNEXT:
108 LODSB ; get char
109FFF:
110 CMP AL,'\' ; beginning of directory
111 JNZ FOK ; no
112 STOSB ; put into user's buffer
113 LODSB ; 1st char of dir is 05?
114 CMP AL,05H
115 JNZ FOK ; no
116FCHANGE:
117 MOV AL,0E5H ; make it E5
118FOK:
119 STOSB ; put into user's buffer
120 OR AL,AL ; final char
121 JNZ FCPYNEXT ; no
122 POP AX
123
124;; 10/29/86 E5 char
125 xor AL,AL ; MZ 19 Jan 84
126 LeaveCrit critDisk
127 transfer Sys_Ret_OK ; no more, bye!
128EndProc $Current_Dir
129
130BREAK <$RmDir -- Remove a directory>
131
132; Inputs:
133; DS:DX Points to asciz name
134; Function:
135; Delete directory if empty
136; Returns:
137; STD XENIX Return
138; AX = error_path_not_found If path bad
139; AX = error_access_denied If
140; Directory not empty
141; Path not directory
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
146
147 procedure $RMDIR,NEAR
148 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
149
150 push dx ; Save ptr to name
151 push ds
152 mov si,dx ; Load ptr into si
153 mov di,offset DOSGroup:OpenBuf ; di = ptr to buf for trans name
154 push di
155 Invoke TransPathNoSet ; Translate the name
156 pop di ; di = ptr to buf for trans name
157 jnc rmlset ; If transpath succeeded, continue
158 pop ds
159 pop dx ; Restore the name
160 error error_path_not_found ; Otherwise, return an error
161
162rmlset:
163 CMP cMeta,-1 ; if (cMeta >= 0)
164 Jnz rmerr ; return (-1);
165 Context ES
166 xor al,al ; al = 0 , ie drive a:
167rmloop: 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.
173
174rmerr:
175 pop ds
176 pop dx ; Restore the name
177 error error_current_directory ; error
178
179rmcont:
180 pop ds
181 pop dx ; Restore the name
182 MOV SI,OFFSET DOSGroup:DOS_RmDIR
183 JMP DoDirCall
184EndProc $RMDIR
185
186BREAK <$ChDir -- Change current directory on a drive>
187
188;
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:
192;
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
196; directory cluster.
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.
207;
208; Inputs:
209; DS:DX Points to asciz name
210; Returns:
211; STD XENIX Return
212; AX = chdir_path_not_found if error
213
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
220ChDirErrP:
221 MOV AL,error_path_not_found
222ChdirErr:
223 transfer SYS_Ret_Err ; oops!
224
225ChDirCrack:
226 Assume DS:DOSGroup
227 CMP cMeta,-1 ; No meta chars allowed.
228 JNZ ChDirErrP
229;
230; We cannot do a ChDir (yet) on a raw CDS. This is treated as a path not
231; found.
232;
233 LES DI,ThisCDS
234 CMP DI,-1 ; if (ThisCDS == NULL)
235 JZ ChDirErrP ; error ();
236 ;
237 ; Find out if the directory exists.
238 ;
239 Invoke DOS_ChDir
240 JC ChDirErr
241;
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
244;
245 LES DI,ThisCDS
246 TEST ES:[DI].curdir_flags,curdir_splice
247 JZ GotCDS
248;
249; The CDS was joined. Let's go back and grab the logical CDS.
250;
251 SaveReg <ES,DI,CX> ; save CDS and cluster...
252 Invoke Get_User_Stack ; get original text
253 ASSUME DS:NOTHING
254 MOV DI,[SI.User_DX]
255 MOV DS,[SI.User_DS]
256 MOV SI,OFFSET DOSGroup:OpenBuf ; spot for translated name
257 XCHG SI,DI
258 XOR AL,AL ; do no splicing
259 SaveReg <DI>
260 Invoke TransPathNoSet ; Munge path
261 RestoreReg <SI>
262 Assume DS:DOSGroup
263;
264; There should NEVER be an error here.
265;
266IF FALSE
267 JNC SKipErr
268 fmt <>,<>,<"$p: Internal CHDIR error\n">
269SkipErr:
270ENDIF
271 LES DI,ThisCDS ; get new CDS
272 MOV ES:[DI].curdir_ID,-1 ; no valid cluster here...
273 RestoreReg <CX,DI,ES>
274;
275; ES:DI point to the physical CDS, CX is the ID (local only)
276;
277GotCDS:
278;
279; wfp_start points to the text. See if it is long enough
280;
281 CALL Check_PathLen ;PTM. ;AN000;
282 JA ChDirErrP
283 TEST ES:[DI].curdir_flags,curdir_isnet
284 JNZ SkipRecency
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;
288setdirclus:
289 MOV ES:[DI].curdir_id,CX
290 LES DI,ThisCDS ; get logical CDS
291SkipRecency:
292 invoke FStrCpy
293 XOR AL,AL
294 transfer Sys_Ret_OK
295EndProc $CHDIR
296
297BREAK <$MkDir - Make a directory entry>
298; Inputs:
299; DS:DX Points to asciz name
300; Function:
301; Make a new directory
302; Returns:
303; STD XENIX Return
304; AX = mkdir_path_not_found if path bad
305; AX = mkdir_access_denied If
306; Directory cannot be created
307; Node already exists
308; Device name given
309; Disk or directory(root) full
310
311 procedure $MKDIR,NEAR
312 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
313 MOV SI,OFFSET DOSGroup:DOS_MkDir
314DoDirCall:
315 MOV DI,OFFSET DOSGroup:OpenBuf ; spot for translated name
316 SaveReg <SI>
317 MOV SI,DX ; get source
318 Invoke TransPath ; go munge the path
319 RestoreReg <SI>
320 JNC MkDirCrack ; no errors, try path
321MkErrP:
322 MOV AL,error_Path_Not_Found ; oops!
323MkErr:
324 transfer Sys_Ret_Err
325MkDirCrack:
326 CMP cMeta,-1
327 JNZ MkErrP
328
329 PUSH SI ;PTM. ;AN000;
330 CALL Check_PathLen ;PTM. check path len > 67 ? ;AN000;
331 POP SI ;PTM. ;AN000;
332 JBE pathok ;PTM. ;AN000;
333 MOV AL,error_Access_Denied ;PTM. ops!
334 transfer Sys_Ret_Err ;PTM.
335pathok:
336 CALL SI ; go get file
337 ASSUME ES:NOTHING
338 JC MkErr ; no errors
339 transfer Sys_Ret_OK
340EndProc $MKDIR
341
342; Inputs:
343; nothing
344; Function:
345; check if final path length greater than 67
346; Returns:
347; Above flag set if > 67
348
349 procedure Check_PathLen,NEAR
350 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGroup
351
352 MOV SI,Wfp_Start
353 entry Check_PathLen2
354 Context <DS>
355 SaveReg <CX>
356 invoke DStrLen
357 CMP CX,DirStrLen
358 RestoreReg <CX>
359 ret
360EndProc Check_PathLen
361CODE ENDS
362END
363 \ No newline at end of file