summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/RENAME.ASM
blob: c7d6caf85380b5fbda5ad886ed34797a4c5cc04f (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
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
;	SCCSID = @(#)rename.asm 1.1 85/04/10
TITLE	DOS_RENAME - Internal RENAME call for MS-DOS
NAME	DOS_RENAME
; Low level routine for renaming files
;
;   DOS_RENAME
;
;   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
.cref
.list

Installed = TRUE

	i_need	RENAMEDMA,BYTE
	i_need	AUXSTACK,BYTE
	i_need	DESTSTART,WORD
	i_need	DIRSTART,WORD
	i_need	CURBUF,DWORD
	I_need	NAME1,BYTE
	i_need	NAME2,BYTE
	i_need	WFP_START,WORD
	i_need	REN_WFP,WORD
	i_need	CURR_DIR_END,WORD
	i_need	DMAADD,DWORD
	i_need	THISCDS,DWORD
	i_need	THISDPB,DWORD
	i_need	THISSFT,DWORD
	i_need	CREATING,BYTE
	i_need	THISDRV,BYTE
	i_need	ATTRIB,BYTE
	i_need	FOUND_DEV,BYTE
	i_need	FAILERR,BYTE
	i_need	EXTERR_LOCUS,BYTE
	i_need	SAVE_BX,WORD

; Inputs:
;	[WFP_START] Points to SOURCE WFP string ("d:/" must be first 3
;		chars, NUL terminated)
;	[CURR_DIR_END] Points to end of Current dir part of string [SOURCE]
;		( = -1 if current dir not involved, else
;		 Points to first char after last "/" of current dir part)
;	[REN_WFP] Points to DEST WFP string ("d:/" must be first 3
;		chars, NUL terminated)
;	[THISCDS] Points to CDS being used
;		(Low word = -1 if NUL CDS (Net direct request))
;	[SATTRIB] Is attribute of search, determines what files can be found
; Function:
;	Rename the specified file(s)
;	NOTE: This routine uses most of AUXSTACK as a temp buffer.
; Outputs:
;	CARRY CLEAR
;	    OK
;	CARRY SET
;	    AX is error code
;		error_file_not_found
;			No match for source, or dest path invalid
;		error_not_same_device
;			Source and dest are on different devices
;		error_access_denied
;			Directory specified (not simple rename),
;			Device name given, Destination exists.
;			NOTE: In third case some renames may have
;			 been done if metas.
;		error_path_not_found
;			Bad path (not in curr dir part if present)
;			SOURCE ONLY
;		error_bad_curr_dir
;			Bad path in current directory part of path
;			SOURCE ONLY
;		error_sharing_violation
;			Deny both access required, generates an INT 24.
; DS preserved, others destroyed

	procedure   DOS_RENAME,NEAR
	DOSAssume   CS,<DS>,"DOS_Rename"
	ASSUME	ES:NOTHING

	Invoke	TestNet
	JNC	LOCAL_RENAME
;	invoke	OWN_SHARE2		       ;IFS.  IFS owns share ?		;AN000;
;	JZ	ifsshare		       ;IFS.  yes			;AN000;
;	PUSH	WORD PTR [DMAADD+2]	       ;IFS.  save DMAADD		;AN000;
;	PUSH	WORD PTR [DMAADD]	       ;IFS.				;AN000;
;
;	invoke	IFS_SEARCH_FIRST	       ;IFS.  search source name	;AN000;
;	JC	nofiles 		       ;IFS.  not found 		;AN000;
rename_next_file:
;	invoke	IFS_REN_DEL_CHECK	       ;IFS.  do share check		;AN000;
;	JNC	share_okok		       ;IFS.  share ok			;AN000;
;	MOV	AX,error_sharing_violation     ;IFS.  share error		;AN000;
;	JMP	SHORT nofiles		       ;IFS.				;AN000;
share_okok:
;	PUSH	CS			       ;IFS.				;AN000;
;	POP	ES			       ;IFS.				;AN000;
;	MOV	SI,[REN_WFP]		       ;IFS. ds:si -> destination name	;AN000;
;	MOV	BX,SI			       ;IFS.				;AN000;
fndnxt: 				       ;IFS.				;AN000;
;	LODSB				       ;IFS.				;AN000;
;	CMP	AL,0			       ;IFS.				;AN000;
;	JNZ	fndnxt			       ;IFS.				;AN000;
;	MOV	DI,SI			       ;IFS. es:di -> end of destinatio ;AN000;
;	ADD	BX,2			       ;IFS.				;AN000;
;	invoke	SkipBack		       ;IFS.				;AN000;
;	INC	DI			       ;IFS. es:di -> last component of ;AN000;
;	MOV	SI,DI			       ;IFS.	      dstination	;AN000;
;	MOV	BX,[SAVE_BX]		       ;IFS. ds:bx -> last component of ;AN000;
;	CALL	NEW_RENAME		       ;IFS.	      source		;AN000;
;	MOV	AX,(multNET SHL 8) OR 17       ;IFS.  replace ? chars with	;AN000;
;	INT	2FH			       ;IFS.  source and issue RENAME	;AN000;
;	JC	nofiles 		       ;IFS.  error			;AN000;
;	invoke	DOS_SEARCH_NEXT 	       ;IFS.  serch next source 	;AN000;
;	JNC	rename_next_file	       ;IFS.  rename next		;AN000;
;	CLC				       ;IFS.  no more files		;AN000;
nofiles:
;	POP	WORD PTR [DMAADD]	       ;IFS. restore DMAADD		;AN000;
;	POP	WORD PTR [DMAADD+2]	       ;IFS.				;AN000;
;	ret				       ;IFS. return			;AN000;
ifsshare:

IF NOT Installed
	transfer NET_RENAME
ELSE
	MOV	AX,(multNET SHL 8) OR 17
	INT	2FH
	return
ENDIF

LOCAL_RENAME:
	MOV	[EXTERR_LOCUS],errLOC_Disk
	MOV	SI,[WFP_START]
	MOV	DI,[REN_WFP]
	MOV	AL,BYTE PTR [SI]
	MOV	AH,BYTE PTR [DI]
	OR	AX,2020H		; Lower case
	CMP	AL,AH
	JZ	SAMEDRV
	MOV	AX,error_not_same_device
	STC
	return

SAMEDRV:
	PUSH	WORD PTR [DMAADD+2]
	PUSH	WORD PTR [DMAADD]
	MOV	WORD PTR [DMAADD+2],DS
	MOV	WORD PTR [DMAADD],OFFSET DOSGROUP:RENAMEDMA
	MOV	[Found_dev],0		; Rename fails on DEVS, assume not a dev
	EnterCrit   critDisk
	invoke	DOS_SEARCH_FIRST	; Sets [NoSetDir] to 1, [CURBUF+2]:BX
					;    points to entry
	JNC	Check_Dev
	CMP	AX,error_no_more_files
	JNZ	GOTERR
	MOV	AX,error_file_not_found
GOTERR:
	STC
RENAME_POP:
	POP	WORD PTR [DMAADD]
	POP	WORD PTR [DMAADD+2]
	LeaveCrit   critDisk
	return

Check_dev:
	MOV	AX,error_access_denied	; Assume error

	PUSH	DS			      ;PTM.				;AN000;
	LDS	SI,[DMAADD]		      ;PTM.  chek if source a dir	;AN000;
	ADD	SI,find_buf_attr	      ;PTM.				;AN000;
	TEST	[SI.dir_attr],attr_directory  ;PTM.				;AN000;
	JZ	notdir			      ;PTM.				;AN000;
	MOV	SI,[REN_WFP]		      ;PTM.  if yes, make sure path	;AN000;
	invoke	Check_Pathlen2		      ;PTM.   length < 67		;AN000;
notdir:
	POP	DS			      ;PTM.				;AN000;
	JA	GOTERR			      ;PTM.				;AN000;

	CMP	[Found_dev],0
	JNZ	GOTERR
; At this point a source has been found.  There is search continuation info (a
; la DOS_SEARCH_NEXT) for the source at RENAMEDMA, together with the first
; directory entry found.
; [THISCDS], [THISDPB], and [THISDRV] are set and will remain correct
; throughout the RENAME since it is known at this point that the source and
; destination are both on the same device.
; [SATTRIB] is also set.
	MOV	SI,BX
	ADD	SI,dir_first
	invoke	REN_DEL_Check
	JNC	REN_OK1
	MOV	AX,error_sharing_violation
	JMP	RENAME_POP

REN_OK1:				;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	invoke	FastOpen_Delete 	; delete dir info in fastopen DOS 3.3
	MOV	SI,[REN_WFP]		; Swap source and destination
	MOV	[WFP_START],SI
	MOV	[CURR_DIR_END],-1	; No current dir on dest
	MOV	WORD PTR [CREATING],0E5FFH  ; Creating, not DEL *.*
					; A rename is like a CREATE_NEW as far
					; as the destination is concerned.
	invoke	GetPathNoSet
;   If this Getpath fails due to file not found, we know all renames will work
;   since no files match the destination name.	If it fails for any other
;   reason, the rename fails on a path not found, or whatever (also fails if
;   we find a device or directory).  If the Getpath succeeds, we aren't sure
;   if the rename should fail because we haven't built an explicit name by
;   substituting for the meta chars in it.  In this case the destination file
;   spec with metas is in [NAME1] and the explicit source name is at RENAMEDMA
;   in the directory entry part.
	JC	NODEST
;;	JZ	BAD_ACC 		; Dest string is a directory		;AC000;
	OR	AH,AH			; Device?
	JNS	SAVEDEST		; No, continue
BAD_ACC:
	MOV	AX,error_access_denied
	STC
RENAME_CLEAN:
	PUSHF				; Save carry state
	PUSH	AX			; and error code (if carry set)
	MOV	AL,[THISDRV]
	invoke	FLUSHBUF
	POP	AX
	CMP	[FAILERR],0
	JNZ	BAD_ERR 		; User FAILed to I 24
	POPF
	JMP	RENAME_POP

BAD_ERR:
	POP	AX			; Saved flags
	MOV	AX,error_path_not_found
	JMP	GOTERR

NODEST:
	JNZ	BAD_PATH
	CMP	[FAILERR],0
	JNZ	BAD_PATH	; Search for dest failed because user FAILed on
				;	I 24
	OR	CL,CL
	JNZ	SAVEDEST
BAD_PATH:
	MOV	AX,error_path_not_found
	STC
	JMP	RENAME_POP

SAVEDEST:
	Context ES
	MOV	DI,OFFSET DOSGROUP:NAME2
	MOV	SI,OFFSET DOSGROUP:NAME1
	MOV	CX,11
	REP	MOVSB			; Save dest with metas at NAME2
	MOV	AX,[DIRSTART]
	MOV	[DESTSTART],AX
BUILDDEST:
	Context ES			; needed due to JMP BUILDDEST below
	MOV	BX,OFFSET DOSGROUP:RENAMEDMA + 21   ; Source of replace chars
	MOV	DI,OFFSET DOSGROUP:NAME1    ; Real dest name goes here
	MOV	SI,OFFSET DOSGROUP:NAME2    ; Raw dest
	MOV	CX,11
	CALL	NEW_RENAME		    ;IFS. replace ? chars		;AN000;

	MOV	[ATTRIB],attr_all	; Stop duplicates with any attributes
	MOV	[CREATING],0FFH
	invoke	DEVNAME 		; Check if we built a device name
	ASSUME	ES:NOTHING
	JNC	BAD_ACC
	MOV	BX,[DESTSTART]
	LES	BP,[THISDPB]
	invoke	SetDirSrch		; Reset search to start of dir
	JC	BAD_ACC 		; Screw up
	invoke	FINDENTRY		; See if new name already exists
	JNC	BAD_ACC 		; Error if found
	CMP	[FAILERR],0
	JNZ	BAD_ACCJ		; Find failed because user FAILed to I 24
	MOV	AX,[DESTSTART]		; DIRSTART of dest
	CMP	AX,WORD PTR [RENAMEDMA + 15]	; DIRSTART of source
	JZ	SIMPLE_RENAME		; If =, just give new name

	MOV	AL,[RENAMEDMA + 21 + dir_attr]
	TEST	AL,attr_directory
	JNZ	BAD_ACCJ		; Can only do a simple rename on dirs,
					; otherwise the .  and ..  entries get
					; wiped.
	MOV	[ATTRIB],AL
	MOV	WORD PTR [THISSFT+2],DS
	MOV	SI,OFFSET DOSGROUP:AUXSTACK - SIZE SF_ENTRY
	MOV	WORD PTR [THISSFT],SI
	MOV	[SI].sf_mode,sharing_compat+open_for_both
	XOR	CX,CX			; Set "device ID" for call into makenode
	invoke	RENAME_MAKE		; This is in mknode
	JNC	GOT_DEST
BAD_ACCJ:
	JMP	BAD_ACC

GOT_DEST:
	SaveReg <BX>
	LES	DI,ThisSFT		; Rename_make entered this into sharing
	Invoke	ShareEnd		; we need to remove it.
	RestoreReg  <BX>
; A zero length entry with the correct new name has now been made at
;   [CURBUF+2]:BX.
	LES	DI,[CURBUF]
	Assert	ISBUF,<ES,DI>,"Got_Dest"

	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:
	MOV	DI,BX
	ADD	DI,dir_attr		; Skip name
	MOV	SI,OFFSET DOSGROUP:RENAMEDMA + 21 + dir_attr
	MOV	CX,(SIZE dir_entry) - dir_attr
	REP	MOVSB
	CALL	GET_SOURCE
	JC	RENAME_OVER
	MOV	DI,BX
	MOV	ES,WORD PTR [CURBUF+2]
	MOV	AL,0E5H
	STOSB				; "free" the source
	JMP	SHORT DIRTY_IT

SIMPLE_RENAME:
	CALL	GET_SOURCE		; Get the source back
	JC	RENAME_OVER
	MOV	DI,BX
	MOV	ES,WORD PTR [CURBUF+2]
	MOV	SI,OFFSET DOSGROUP:NAME1    ; New Name
	MOV	CX,11
	REP	MOVSB
DIRTY_IT:
	MOV	DI,WORD PTR [CURBUF]

	TEST	ES:[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	ES:[DI.buf_flags],buf_dirty
yesdirty2:
	Assert	ISBUF,<ES,DI>,"Dirty_it"
NEXT_SOURCE:
	MOV	SI,OFFSET DOSGROUP:RENAMEDMA + 1    ;Name
;
; WARNING!  Rename_Next leaves the disk critical section *ALWAYS*.  We need
; to enter it before going to RENAME_Next.
;
	EnterCrit   critDisk
	MOV	[CREATING],0	; Correct setting for search (we changed it
				;   to FF when we made the prev new file).
	invoke	RENAME_NEXT
;
; Note, now, that we have exited the previous ENTER and so are back to where
; we were before.
;
	JC	RENAME_OVER
	LEA	SI,[BX].dir_First
	invoke	REN_DEL_Check
	JNC	REN_OK2
	MOV	AX,error_sharing_violation
	JMP	RENAME_CLEAN

REN_OK2:				;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	invoke	FastOpen_Delete 	; delete dir info in fastopen DOS 3.3
	JMP	BUILDDEST

RENAME_OVER:
	CLC
	JMP	RENAME_CLEAN

; Inputs:
;	RENAMEDMA has source info
; Function:
;	Re-find the source
; Output:
;	[CURBUF] set
;	[CURBUF+2]:BX points to entry
;	Carry set if error (currently user FAILed to I 24)
; DS preserved, others destroyed

GET_SOURCE:
	DOSAssume   CS,<DS>,"Get_Source"
	ASSUME	ES:NOTHING

	MOV	BX,WORD PTR [RENAMEDMA + 15]	; DirStart
	LES	BP,ThisDPB
	invoke	SetDirSrch
	retc
	invoke	StartSrch
	MOV	AX,WORD PTR [RENAMEDMA + 13]	; Lastent
	invoke	GetEnt
	return

EndProc DOS_RENAME

;Input: DS:SI -> raw string with ?
;	ES:DI -> destination string
;	DS:BX -> source string
;Function: replace ? chars of raw string with chars in source string and
;	   put in destination string
;Output: ES:DI-> new string



	procedure   NEW_RENAME,NEAR
	DOSAssume   CS,<DS>,"DOS_Rename"
	ASSUME	ES:NOTHING
NEWNAM:
	LODSB
	CMP	AL,"?"
	JNZ	NOCHG
	MOV	AL,[BX] 		; Get replace char
NOCHG:
	STOSB
	INC	BX			; Next replace char
	LOOP	NEWNAM
	return

EndProc NEW_RENAME

CODE	ENDS
    END