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
|