]> wirehaze git hosting - MS-DOS.git/blob - v2.0/source/DIRCALL.ASM

wirehaze git hosting

Optimized PNG's
[MS-DOS.git] / v2.0 / source / DIRCALL.ASM
1 TITLE DIRCALL - Directory manipulation internal calls
2 NAME DIRCALL
3
4 ; $MKDIR
5 ; $CHDIR
6 ; $RMDIR
7
8 .xlist
9 INCLUDE DOSSEG.ASM
10
11 CODE SEGMENT BYTE PUBLIC 'CODE'
12 ASSUME SS:DOSGROUP,CS:DOSGROUP
13
14 .xcref
15 INCLUDE DOSSYM.ASM
16 INCLUDE DEVSYM.ASM
17 .cref
18 .list
19
20 ifndef Kanji
21 Kanji equ 0
22 endif
23
24 i_need AUXSTACK,BYTE
25 i_need NoSetDir,BYTE
26 i_need CURBUF, DWORD
27 i_need DIRSTART,WORD
28 i_need THISDPB,DWORD
29 i_need NAME1,BYTE
30 i_need LASTENT,WORD
31 i_need ATTRIB,BYTE
32 i_need THISFCB,DWORD
33 i_need AUXSTACK,BYTE
34 i_need CREATING,BYTE
35 i_need DRIVESPEC,BYTE
36 i_need ROOTSTART,BYTE
37 i_need SWITCH_CHARACTER,BYTE
38
39 extrn sys_ret_ok:near,sys_ret_err:near
40
41
42 ; XENIX CALLS
43 BREAK <$MkDir - Make a directory entry>
44 MKNERRJ: JMP MKNERR
45 NODEEXISTSJ: JMP NODEEXISTS
46 procedure $MKDIR,NEAR
47 ASSUME DS:NOTHING,ES:NOTHING
48
49 ; Inputs:
50 ; DS:DX Points to asciz name
51 ; Function:
52 ; Make a new directory
53 ; Returns:
54 ; STD XENIX Return
55 ; AX = mkdir_path_not_found if path bad
56 ; AX = mkdir_access_denied If
57 ; Directory cannot be created
58 ; Node already exists
59 ; Device name given
60 ; Disk or directory(root) full
61 invoke validate_path
62 JC MKNERRJ
63 MOV SI,DX
64 MOV WORD PTR [THISFCB+2],SS
65 MOV WORD PTR [THISFCB],OFFSET DOSGROUP:AUXSTACK-40 ; Scratch space
66 MOV AL,attr_directory
67 MOV WORD PTR [CREATING],0E500h
68 invoke MAKENODE
69 ASSUME DS:DOSGROUP
70 MOV AL,mkdir_path_not_found
71 JC MKNERRJ
72 JNZ NODEEXISTSJ
73 LDS DI,[CURBUF]
74 ASSUME DS:NOTHING
75 SUB SI,DI
76 PUSH SI ; Pointer to fcb_FIRCLUS
77 PUSH [DI.BUFSECNO] ; Sector of new node
78 PUSH SS
79 POP DS
80 ASSUME DS:DOSGROUP
81 PUSH [DIRSTART] ; Parent for .. entry
82 XOR AX,AX
83 MOV [DIRSTART],AX ; Null directory
84 invoke NEWDIR
85 JC NODEEXISTSPOPDEL ; No room
86 invoke GETENT ; First entry
87 LES DI,[CURBUF]
88 MOV ES:[DI.BUFDIRTY],1
89 ADD DI,BUFINSIZ ; Point at buffer
90 MOV AX,202EH ; ". "
91 STOSW
92 MOV DX,[DIRSTART] ; Point at itself
93 invoke SETDOTENT
94 MOV AX,2E2EH ; ".."
95 STOSW
96 POP DX ; Parent
97 invoke SETDOTENT
98 LES BP,[THISDPB]
99 POP DX ; Entry sector
100 XOR AL,AL ; Pre read
101 invoke GETBUFFR
102 MOV DX,[DIRSTART]
103 LDS DI,[CURBUF]
104 ASSUME DS:NOTHING
105 ZAPENT:
106 POP SI ; fcb_Firclus pointer
107 ADD SI,DI
108 MOV [SI],DX
109 XOR DX,DX
110 MOV [SI+2],DX
111 MOV [SI+4],DX
112 DIRUP:
113 MOV [DI.BUFDIRTY],1
114 PUSH SS
115 POP DS
116 ASSUME DS:DOSGROUP
117 MOV AL,ES:[BP.dpb_drive]
118 invoke FLUSHBUF
119 SYS_RET_OKJ:
120 JMP SYS_RET_OK
121
122 NODEEXISTSPOPDEL:
123 POP DX ; Parent
124 POP DX ; Entry sector
125 LES BP,[THISDPB]
126 XOR AL,AL ; Pre read
127 invoke GETBUFFR
128 LDS DI,[CURBUF]
129 ASSUME DS:NOTHING
130 POP SI ; dir_first pointer
131 ADD SI,DI
132 SUB SI,dir_first ; Point back to start of dir entry
133 MOV BYTE PTR [SI],0E5H ; Free the entry
134 CALL DIRUP
135 NODEEXISTS:
136 MOV AL,mkdir_access_denied
137 MKNERR:
138 JMP SYS_RET_ERR
139 $MKDIR ENDP
140
141 BREAK <$ChDir -- Change current directory on a drive>
142 procedure $CHDIR,NEAR
143 ASSUME DS:NOTHING,ES:NOTHING
144
145 ; Inputs:
146 ; DS:DX Points to asciz name
147 ; Function:
148 ; Change current directory
149 ; Returns:
150 ; STD XENIX Return
151 ; AX = chdir_path_not_found if error
152
153 invoke validate_path
154 JC PathTooLong
155
156 PUSH DS
157 PUSH DX
158 MOV SI,DX
159 invoke GETPATH
160 JC PATHNOGOOD
161 JNZ PATHNOGOOD
162 ASSUME DS:DOSGROUP
163 MOV AX,[DIRSTART]
164 MOV BX,AX
165 XCHG BX,ES:[BP.dpb_current_dir]
166 OR AX,AX
167 POP SI
168 POP DS
169 ASSUME DS:NOTHING
170 JZ SYS_RET_OKJ
171 MOV DI,BP
172 ADD DI,dpb_dir_text
173 MOV DX,DI
174 CMP [DRIVESPEC],0
175 JZ NODRIVESPEC
176 INC SI
177 INC SI
178 NODRIVESPEC:
179 MOV CX,SI
180 CMP [ROOTSTART],0
181 JZ NOTROOTPATH
182 INC SI
183 INC CX
184 JMP SHORT COPYTHESTRINGBXZ
185 NOTROOTPATH:
186 OR BX,BX ; Previous path root?
187 JZ COPYTHESTRING ; Yes
188 XOR BX,BX
189 ENDLOOP:
190 CMP BYTE PTR ES:[DI],0
191 JZ PATHEND
192 INC DI
193 INC BX
194 JMP SHORT ENDLOOP
195 PATHEND:
196 MOV AL,'/'
197 CMP AL,[switch_character]
198 JNZ SLASHOK
199 MOV AL,'\' ; Use the alternate character
200 SLASHOK:
201 STOSB
202 INC BX
203 JMP SHORT CHECK_LEN
204
205 PATHNOGOOD:
206 POP AX
207 POP AX
208 PATHTOOLONG:
209 error error_path_not_found
210
211 ASSUME DS:NOTHING
212
213 INCBXCHK:
214 INC BX
215 BXCHK:
216 CMP BX,DIRSTRLEN
217 return
218
219 COPYTHESTRINGBXZ:
220 XOR BX,BX
221 COPYTHESTRING:
222 LODSB
223 OR AL,AL
224
225 JNZ FOOB
226 JMP CPSTDONE
227 FOOB:
228 CMP AL,'.'
229 JZ SEEDOT
230 CALL COPYELEM
231 CHECK_LEN:
232 CMP BX,DIRSTRLEN
233 JB COPYTHESTRING
234 MOV AL,ES:[DI-1]
235 invoke PATHCHRCMP
236 JNZ OK_DI
237 DEC DI
238 OK_DI:
239 XOR AL,AL
240 STOSB ; Correctly terminate the path
241 MOV ES:[BP.dpb_current_dir],-1 ; Force re-validation
242 JMP SHORT PATHTOOLONG
243
244 SEEDOT:
245 LODSB
246 OR AL,AL ; Check for null
247 JZ CPSTDONEDEC
248 CMP AL,'.'
249 JNZ COPYTHESTRING ; eat ./
250 CALL DELELMES ; have ..
251 LODSB ; eat the /
252 OR AL,AL ; Check for null
253 JZ CPSTDONEDEC
254 JMP SHORT COPYTHESTRING
255
256 ; Copy one element from DS:SI to ES:DI include trailing / not trailing null
257 ; LODSB has already been done
258 COPYELEM:
259 PUSH DI ; Save in case too long
260 PUSH CX
261 MOV CX,800h ; length of filename
262 MOV AH,'.' ; char to stop on
263 CALL CopyPiece ; go for it!
264 CALL BXCHK ; did we go over?
265 JAE POPCXDI ; yep, go home
266 CMP AH,AL ; did we stop on .?
267 JZ CopyExt ; yes, go copy ext
268 OR AL,AL ; did we end on nul?
269 JZ DECSIRet ; yes, bye
270 CopyPathEnd:
271 STOSB ; save the path char
272 CALL INCBXCHK ; was there room for it?
273 JAE POPCXDI ; Nope
274 INC SI ; guard against following dec
275 DECSIRET:
276 DEC SI ; point back at null
277 POP CX
278 POP AX ; toss away saved DI
279 return
280 POPCXDI:
281 POP CX ; restore
282 POP DI ; point back...
283 return
284 CopyExt:
285 STOSB ; save the dot
286 CALL INCBXCHK ; room?
287 JAE POPCXDI ; nope.
288 LODSB ; get next char
289 XOR AH,AH ; NUL here
290 MOV CX,300h ; at most 3 chars
291 CALL CopyPiece ; go copy it
292 CALL BXCHK ; did we go over
293 JAE POPCXDI ; yep
294 OR AL,AL ; sucessful end?
295 JZ DECSIRET ; yes
296 JMP CopyPathEnd ; go stash path char
297
298 DELELMES:
299 ; Delete one path element from ES:DI
300 DEC DI ; the '/'
301 DEC BX
302
303 IF KANJI
304 PUSH AX
305 PUSH CX
306 PUSH DI
307 PUSH DX
308 MOV CX,DI
309 MOV DI,DX
310 DELLOOP:
311 CMP DI,CX
312 JZ GOTDELE
313 MOV AL,ES:[DI]
314 INC DI
315 invoke TESTKANJ
316 JZ NOTKANJ11
317 INC DI
318 JMP DELLOOP
319
320 NOTKANJ11:
321 invoke PATHCHRCMP
322 JNZ DELLOOP
323 MOV DX,DI ; Point to char after '/'
324 JMP DELLOOP
325
326 GOTDELE:
327 MOV DI,DX
328 POP DX
329 POP AX ; Initial DI
330 SUB AX,DI ; Distance moved
331 SUB BX,AX ; Set correct BX
332 POP CX
333 POP AX
334 return
335 ELSE
336 DELLOOP:
337 CMP DI,DX
338 retz
339 PUSH AX
340 MOV AL,ES:[DI-1]
341 invoke PATHCHRCMP
342 POP AX
343 retz
344 DEC DI
345 DEC BX
346 JMP SHORT DELLOOP
347 ENDIF
348
349 CPSTDONEDEC:
350 DEC DI ; Back up over trailing /
351 CPSTDONE:
352 STOSB ; The NUL
353 JMP SYS_RET_OK
354
355 ; copy a piece CH chars max until the char in AH (or path or NUL)
356 CopyPiece:
357 STOSB ; store the character
358 INC CL ; moved a byte
359 CALL INCBXCHK ; room enough?
360 JAE CopyPieceRet ; no, pop CX and DI
361 OR AL,AL ; end of string?
362 JZ CopyPieceRet ; yes, dec si and return
363
364 IF KANJI
365 CALL TestKanj ; was it kanji?
366 JZ NotKanj ; nope
367 MOVSB ; move the next byte
368 CALL INCBXCHK ; room for it?
369 JAE CopyPieceRet ; nope
370 INC CL ; moved a byte
371 NotKanj:
372 ENDIF
373
374 CMP CL,CH ; move too many?
375 JBE CopyPieceNext ; nope
376
377 IF KANJI
378 CALL TestKanj ; was the last byte kanji
379 JZ NotKanj2 ; no only single byte backup
380 DEC DI ; back up a char
381 DEC BX
382 NotKanj2:
383 ENDIF
384
385 DEC DI ; back up a char
386 DEC BX
387 CopyPieceNext:
388 LODSB ; get next character
389 invoke PathChrCmp ; end of road?
390 JZ CopyPieceRet ; yep, return and don't dec SI
391 CMP AL,AH ; end of filename?
392 JNZ CopyPiece ; go do name
393 CopyPieceRet:
394 return ; bye!
395
396 $CHDIR ENDP
397
398 BREAK <$RmDir -- Remove a directory>
399 NOPATHJ: JMP NOPATH
400
401 procedure $RMDIR,NEAR ; System call 47
402 ASSUME DS:NOTHING,ES:NOTHING
403
404 ; Inputs:
405 ; DS:DX Points to asciz name
406 ; Function:
407 ; Delete directory if empty
408 ; Returns:
409 ; STD XENIX Return
410 ; AX = rmdir_path_not_found If path bad
411 ; AX = rmdir_access_denied If
412 ; Directory not empty
413 ; Path not directory
414 ; Root directory specified
415 ; Directory malformed (. and .. not first two entries)
416 ; AX = rmdir_current_directory
417
418 invoke Validate_path
419 JC NoPathJ
420 MOV SI,DX
421 invoke GETPATH
422 JC NOPATHJ
423 ASSUME DS:DOSGROUP
424 JNZ NOTDIRPATH
425 MOV DI,[DIRSTART]
426 OR DI,DI
427 JZ NOTDIRPATH
428 MOV CX,ES:[BP.dpb_current_dir]
429 CMP CX,-1
430 JNZ rmdir_current_dir_check
431 invoke GetCurrDir
432 invoke Get_user_stack
433 MOV DX,[SI.user_DX]
434 MOV DS,[SI.user_DS]
435 JMP $RMDIR
436
437 NOTDIRPATHPOP:
438 POP AX
439 POP AX
440 NOTDIRPATH:
441 error error_access_denied
442
443 rmdir_current_dir_check:
444 CMP DI,CX
445 JNZ rmdir_get_buf
446 error error_current_directory
447
448 rmdir_get_buf:
449 LDS DI,[CURBUF]
450 ASSUME DS:NOTHING
451 SUB BX,DI
452 PUSH BX ; Save entry pointer
453 PUSH [DI.BUFSECNO] ; Save sector number
454 PUSH SS
455 POP DS
456 ASSUME DS:DOSGROUP
457 PUSH SS
458 POP ES
459 MOV DI,OFFSET DOSGROUP:NAME1
460 MOV AL,'?'
461 MOV CX,11
462 REP STOSB
463 XOR AL,AL
464 STOSB
465 invoke STARTSRCH
466 invoke GETENTRY
467 MOV DS,WORD PTR [CURBUF+2]
468 ASSUME DS:NOTHING
469 MOV SI,BX
470 LODSW
471 CMP AX,(' ' SHL 8) OR '.'
472 JNZ NOTDIRPATHPOP
473 ADD SI,32-2
474 LODSW
475 CMP AX,('.' SHL 8) OR '.'
476 JNZ NOTDIRPATHPOP
477 PUSH SS
478 POP DS
479 ASSUME DS:DOSGROUP
480 MOV [LASTENT],2 ; Skip . and ..
481 invoke GETENTRY
482 MOV [ATTRIB],attr_directory+attr_hidden+attr_system
483 invoke SRCH
484 JNC NOTDIRPATHPOP
485 LES BP,[THISDPB]
486 MOV BX,[DIRSTART]
487 invoke RELEASE
488 POP DX
489 XOR AL,AL
490 invoke GETBUFFR
491 LDS DI,[CURBUF]
492 ASSUME DS:NOTHING
493 POP BX
494 ADD BX,DI
495 MOV BYTE PTR [BX],0E5H ; Free the entry
496 JMP DIRUP
497
498 NOPATH:
499 error error_path_not_found
500
501 $RMDIR ENDP
502
503 do_ext
504
505 CODE ENDS
506 END
507