summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/DIRCALL.ASM
blob: 3c79fe0f3be1587d4860729f3d1624e963dc81d6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
;	SCCSID = @(#)dircall.asm	1.1 85/04/10
;	SCCSID = @(#)dircall.asm	1.1 85/04/10
TITLE DIRCALL - Directory manipulation internal calls
NAME  DIRCALL
; Low level directory manipulation routines for making removing and
;   verifying local or NET directories
;
;   DOS_MKDIR
;   DOS_CHDIR
;   DOS_RMDIR
;
;   Modification history:
;
;	Created: ARR 30 March 1983
;

;
; get the appropriate segment definitions
;
.xlist
include dosseg.asm

CODE	SEGMENT BYTE PUBLIC  'CODE'
	ASSUME	SS:DOSGROUP,CS:DOSGROUP

.xcref
INCLUDE DOSSYM.INC
INCLUDE DEVSYM.INC
INCLUDE FASTOPEN.INC
INCLUDE FASTXXXX.INC
.cref
.list

Installed = TRUE

	i_need	THISSFT,DWORD
	i_need	THISCDS,DWORD
	i_need	NoSetDir,BYTE
	i_need	CURBUF, DWORD
	i_need	DIRSTART,WORD
	i_need	THISDPB,DWORD
	i_need	NAME1,BYTE
	i_need	LASTENT,WORD
	i_need	SATTRIB,BYTE
	i_need	ATTRIB,BYTE
	i_need	ALLOWED,BYTE
	i_need	FAILERR,BYTE
	i_need	RenBuf,BYTE
	i_need	FastOpenFlg,BYTE		  ; DOS 3.3
	i_need	FastOpenTable,BYTE		  ; DOS 3.3
	i_need	WFP_START,WORD			  ; DOS 3.3
	i_need	HIGH_SECTOR,WORD		  ; F.C. >32mb

BREAK <DOS_MkDir - Make a directory entry>

; Inputs:
;	[WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL
;		terminated)
;	[CURR_DIR_END] Points to end of Current dir part of string
;		( = -1 if current dir not involved, else
;		 Points to first char after last "/" of current dir part)
;	[THISCDS] Points to CDS being used
;		(Low word = -1 if NUL CDS (Net direct request))
; Function:
;	Make a new directory
; Returns:
;	Carry Clear
;		No error
;	Carry Set
;	    AX is error code
;		error_path_not_found
;			Bad path (not in curr dir part if present)
;		error_bad_curr_dir
;			Bad path in current directory part of path
;		error_access_denied
;			Already exists, device name
; DS preserved, Others destroyed

	procedure   DOS_MKDIR,NEAR
	DOSAssume   CS,<DS>,"DOS_MkDir"
	ASSUME	ES:NOTHING

	Invoke	TestNet
	JNC	local_mkdir
IF NOT Installed
	transfer NET_MKDIR
ELSE
	MOV	AX,(multNET SHL 8) OR 3
	INT	2FH
	return
ENDIF

NODEACCERRJ:
	MOV	AX,error_access_denied
BadRet:
	STC
	LeaveCrit   critDisk
	return

PATHNFJ:
	LeaveCrit   critDisk
	transfer SET_MKND_ERR		; Map the MakeNode error and return

LOCAL_MKDIR:
	EnterCrit   critDisk
;
; MakeNode requires an SFT to fiddle with.  We Use a temp spot (RENBUF)
;
	MOV	WORD PTR [THISSFT+2],SS
	MOV	WORD PTR [THISSFT],OFFSET DOSGroup:RenBuf
;
;  NOTE: Need WORD PTR because MASM takes type of
;   TempSFT (byte) instead of type of sf_mft (word).
;
	MOV	WORD PTR RenBuf.sf_mft,0    ; make sure SHARER won't complain.
	MOV	AL,attr_directory
	invoke	MAKENODE

	JC	PATHNFJ
	CMP	AX,3
	JZ	NODEACCERRJ	; Can't make a device into a directory
	LES	BP,[THISDPB]	; Makenode zaps this
	LDS	DI,[CURBUF]
ASSUME	DS:NOTHING
	SUB	SI,DI
	PUSH	SI		; Pointer to dir_first
	PUSH	WORD PTR [DI.buf_sector+2]	    ;F.C. >32mb

	PUSH	WORD PTR [DI.buf_sector] ; Sector of new node
	context DS
	PUSH	[DIRSTART]	; Parent for .. entry
	XOR	AX,AX
	MOV	[DIRSTART],AX	; Null directory
	invoke	NEWDIR
	JC	NODEEXISTSPOPDEL    ; No room
	invoke	GETENT		; First entry
	JC	NODEEXISTSPOPDEL    ; Screw up
	LES	DI,[CURBUF]

	TEST	ES:[DI.buf_flags],buf_dirty  ;LB. if already dirty		;AN000;
	JNZ	yesdirty		  ;LB.	  don't increment dirty count   ;AN000;
	invoke	INC_DIRTY_COUNT 	  ;LB.					;AN000;
	OR	ES:[DI.buf_flags],buf_dirty
yesdirty:
	ADD	DI,BUFINSIZ	; Point at buffer
	MOV	AX,202EH	; ". "
	MOV	DX,[DIRSTART]	; Point at itself
	invoke	SETDOTENT
	MOV	AX,2E2EH	; ".."
	POP	DX		; Parent
	invoke	SETDOTENT
	LES	BP,[THISDPB]
	MOV	[ALLOWED],allowed_FAIL + allowed_RETRY
	POP	DX		; Entry sector
	POP	[HIGH_SECTOR]	;F.C. >32mb

	XOR	AL,AL		; Pre read
	invoke	GETBUFFR
	JC	NODEEXISTSP
	MOV	DX,[DIRSTART]
	LDS	DI,[CURBUF]
ASSUME	DS:NOTHING
	OR	[DI.buf_flags],buf_isDIR
	POP	SI		; dir_first pointer
	ADD	SI,DI
	MOV	[SI],DX
	XOR	DX,DX
	MOV	[SI+2],DX	; Zero size
	MOV	[SI+4],DX
DIRUP:
	TEST	[DI.buf_flags],buf_dirty  ;LB. if already dirty 		;AN000;
	JNZ	yesdirty2		  ;LB.	  don't increment dirty count   ;AN000;
	invoke	INC_DIRTY_COUNT 	  ;LB.					;AN000;
	OR	[DI.buf_flags],buf_dirty	; Dirty buffer
yesdirty2:
	context DS
	MOV	AL,ES:[BP.dpb_drive]
	invoke	FLUSHBUF
	MOV	AX,error_access_denied
	LeaveCrit   critDisk
	return

NODEEXISTSPOPDEL:
	POP	DX		; Parent
	POP	DX		; Entry sector
	POP	[HIGH_SECTOR]	; F.C. >32mb

	LES	BP,[THISDPB]
	MOV	[ALLOWED],allowed_FAIL + allowed_RETRY
	XOR	AL,AL		; Pre read
	invoke	GETBUFFR
	JC	NODEEXISTSP
	LDS	DI,[CURBUF]
ASSUME	DS:NOTHING
	OR	[DI.buf_flags],buf_isDIR
	POP	SI		; dir_first pointer
	ADD	SI,DI
	SUB	SI,dir_first	;Point back to start of dir entry
	MOV	BYTE PTR [SI],0E5H    ; Free the entry
	CALL	DIRUP		; Error doesn't matter since erroring anyway
NODEEXISTS:
	JMP	NODEACCERRJ

NODEEXISTSP:
	POP	SI		; Clean stack
	JMP	NODEEXISTS

EndProc DOS_MKDIR

BREAK <DOS_ChDir -- Verify a directory>

; Inputs:
;	[WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL
;		terminated)
;	[CURR_DIR_END] Points to end of Current dir part of string
;		( = -1 if current dir not involved, else
;		 Points to first char after last "/" of current dir part)
;	[THISCDS] Points to CDS being used May not be NUL
; Function:
;	Validate the path for potential new current directory
; Returns:
;	NOTE:
;	    [SATTRIB] is modified by this call
;	Carry Clear
;	    CX is cluster number of the DIR, LOCAL CDS ONLY
;		Caller must NOT set ID fields on a NET CDS.
;	Carry Set
;	    AX is error code
;		error_path_not_found
;			Bad path
;		error_access_denied
;			device or file name
; DS preserved, Others destroyed

	procedure   DOS_CHDIR,NEAR
	DOSAssume   CS,<DS>,"DOS_Chdir"
	ASSUME	ES:NOTHING

	Invoke	TestNet
	JNC	LOCAL_CHDIR
IF NOT Installed
	transfer NET_CHDIR
ELSE
	MOV	AX,(multNET SHL 8) OR 5
	INT	2FH
	return
ENDIF

LOCAL_CHDIR:
	EnterCrit   critDisk
	TEST	ES:[DI.curdir_flags],curdir_splice ;PTM.
	JZ	nojoin				   ;PTM.
	MOV	ES:[DI.curdir_ID],0FFFFH	   ;PTM.
nojoin:
	MOV	[NoSetDir],FALSE
	MOV	[SATTRIB],attr_directory+attr_system+attr_hidden
				; Dir calls can find these
; DOS 3.3  6/24/86 FastOpen

	OR	[FastOpenFlg],FastOpen_Set	   ; set fastopen flag
	invoke	GetPath
	PUSHF									;AN000;
	AND	[FastOpenFlg],Fast_yes		   ; clear it all		;AC000;
	POPF									;AN000;
; DOS 3.3  6/24/86 FastOpen
	MOV	AX,error_path_not_found
	JC	ChDirDone
	JNZ	NOTDIRPATH	; Path not a DIR
	MOV	CX,[DIRSTART]	; Get cluster number
	CLC
ChDirDone:
	LeaveCrit   critDisk
	return

EndProc DOS_CHDIR

BREAK <DOS_RmDir -- Remove a directory>

; Inputs:
;	[WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL
;		terminated)
;	[CURR_DIR_END] Points to end of Current dir part of string
;		( = -1 if current dir not involved, else
;		 Points to first char after last "/" of current dir part)
;	[THISCDS] Points to CDS being used
;		(Low word = -1 if NUL CDS (Net direct request))
; Function:
;	Remove a directory
;	NOTE: Attempt to remove current directory must be detected by caller
; Returns:
;	NOTE:
;	    [SATTRIB] is modified by this call
;	Carry Clear
;		No error
;	Carry Set
;	    AX is error code
;		error_path_not_found
;			Bad path (not in curr dir part if present)
;		error_bad_curr_dir
;			Bad path in current directory part of path
;		error_access_denied
;			device or file name, root directory
;			Bad directory ('.' '..' messed up)
; DS preserved, Others destroyed

	procedure   DOS_RMDIR,NEAR
	DOSAssume   CS,<DS>,"DOS_RmDir"
	ASSUME	ES:NOTHING

	Invoke	TestNet
	JNC	Local_RmDIR
IF NOT Installed
	transfer NET_RMDIR
ELSE
	MOV	AX,(multNET SHL 8) OR 1
	INT	2FH
	return
ENDIF

LOCAL_RMDIR:
	EnterCrit   critDisk
	MOV	[NoSetDir],0
	MOV	[SATTRIB],attr_directory+attr_system+attr_hidden
				; Dir calls can find these
	invoke	GetPath
	JC	NOPATH		; Path not found
	JNZ	NOTDIRPATH	; Path not a DIR
	MOV	DI,[DIRSTART]
	OR	DI,DI		; Root ?
	JNZ	rmdir_get_buf	; No
	JMP	SHORT NOTDIRPATH

NOPATH:
	MOV	AX,error_path_not_found
	JMP	BadRet

NOTDIRPATHPOP:
	POP	AX			  ;F.C. >32mb
	POP	AX
NOTDIRPATHPOP2:
	POP	AX
NOTDIRPATH:
	JMP	NodeAccErrJ

rmdir_get_buf:
	LDS	DI,[CURBUF]
ASSUME	DS:NOTHING
	SUB	BX,DI		; Compute true offset
	PUSH	BX		; Save entry pointer
	PUSH	WORD PTR [DI.buf_sector+2] ;F.C. >32mb
	PUSH	WORD PTR [DI.buf_sector] ; Save sector number
	context DS
	context ES
	MOV	DI,OFFSET DOSGROUP:NAME1
	MOV	AL,'?'
	MOV	CX,11
	REP	STOSB
	XOR	AL,AL
	STOSB			; Nul terminate it
	invoke	STARTSRCH	; Set search
	invoke	GETENTRY	; Get start of directory
	JC	NOTDIRPATHPOP	; Screw up
	MOV	DS,WORD PTR [CURBUF+2]
ASSUME	DS:NOTHING
	MOV	SI,BX
	LODSW
	CMP	AX,(' ' SHL 8) OR '.'   ; First entry '.'?
	JNZ	NOTDIRPATHPOP		; Nope
	ADD	SI,(SIZE dir_entry) - 2 ; Next entry
	LODSW
	CMP	AX,('.' SHL 8) OR '.'   ; Second entry '..'?
	JNZ	NOTDIRPATHPOP		; Nope
	context DS
	MOV	[LASTENT],2		; Skip . and ..
	invoke	GETENTRY		; Get next entry
	JC	NOTDIRPATHPOP		; Screw up
	MOV	[ATTRIB],attr_directory+attr_hidden+attr_system
	invoke	SRCH			; Do a search
	JNC	NOTDIRPATHPOP		; Found another entry!
	CMP	[FAILERR],0
	JNZ	NOTDIRPATHPOP		; Failure of search due to I 24 FAIL
	LES	BP,[THISDPB]
	MOV	BX,[DIRSTART]
;; FastSeek 10/27/86
	invoke	Delete_FSeek		; delete the fastseek entry
;; FastSeek 10/27/86
	invoke	RELEASE 		; Release data in sub dir
	JC	NOTDIRPATHPOP		; Screw up
	POP	DX			; Sector # of entry
	POP	[HIGH_SECTOR]		; F.C. >32mb

	MOV	[ALLOWED],allowed_FAIL + allowed_RETRY
	XOR	AL,AL			; Pre read
	invoke	GETBUFFR		; Get sector back
	JC	NOTDIRPATHPOP2		; Screw up
	LDS	DI,[CURBUF]
ASSUME	DS:NOTHING
	OR	[DI.buf_flags],buf_isDIR
	POP	BX			; Pointer to start of entry
	ADD	BX,DI			; Corrected
	MOV	BYTE PTR [BX],0E5H	; Free the entry

;DOS 3.3 FastOpen  6/16/86  F.C.
	PUSH	DS
	context DS
	invoke	FastOpen_Delete 	; call fastopen to delete an entry
	POP	DS
;DOS 3.3 FastOpen  6/16/86  F.C.

	JMP	DIRUP			; In MKDIR, dirty buffer and flush

EndProc DOS_RMDIR

CODE	ENDS
    END