1 ; SCCSID = @(#)delete.asm 1.3 85/10/18
2 ; SCCSID = @(#)delete.asm 1.3 85/10/18
3 TITLE DOS_DELETE
- Internal DELETE
call for
MS-DOS
5 ; Low level routine for deleting files
9 ; FastOpen_Delete ; DOS 3.3
10 ; FastOpen_Update ; DOS 3.3
11 ; FastSeek_Open ; DOS 4.00
12 ; FSeek_dispatch ; DOS 4.00
13 ; FastSeek_Close ; DOS 4.00
14 ; FastSeek_Delete ; DOS 4.00
15 ; Delete_FSeek ; DOS 4.00
16 ; FastSeek_Lookup ; DOS 4.00
17 ; FastSeek_Insert ; DOS 4.00
18 ; FastSeek_Truncate ; DOS 4.00
23 ; A000 version 4.00 Jan. 1988
27 ; get the appropriate segment definitions
32 CODE SEGMENT BYTE PUBLIC 'CODE'
33 ASSUME
SS:DOSGROUP
,CS:DOSGROUP
58 i_need VOLCHNG_FLAG
,BYTE
60 i_need FastOpenTable
,BYTE ; DOS 3.3
61 i_need FastTable
,BYTE ; DOS 4.00
62 i_need FSeek_drive
,BYTE ; DOS 4.00
63 i_need FSeek_firclus
,WORD ; DOS 4.00
64 i_need FSeek_logclus
,WORD ; DOS 4.00
65 i_need FSeek_logsave
,WORD ; DOS 4.00
66 i_need FastSeekflg
,BYTE ; DOS 4.00
67 i_need Del_ExtCluster
,WORD ; DOS 4.00
68 i_need SAVE_BX
,WORD ; DOS 4.00
73 ; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL
75 ; [CURR_DIR_END] Points to end of Current dir part of string
76 ; ( = -1 if current dir not involved, else
77 ; Points to first char after last "/" of current dir part)
78 ; [THISCDS] Points to CDS being used
79 ; (Low word = -1 if NUL CDS (Net direct request))
80 ; [SATTRIB] Is attribute of search, determines what files can be found
82 ; Delete the specified file(s)
88 ; error_file_not_found
89 ; Last element of path not found
90 ; error_path_not_found
91 ; Bad path (not in curr dir part if present)
93 ; Bad path in current directory part of path
95 ; Attempt to delete device or directory
96 ; ***error_sharing_violation***
97 ; Deny both access required, generates an INT 24.
98 ; This error is NOT returned. The INT 24H is generated,
99 ; and the file is ignored (not deleted). Delete will
100 ; simply continue on looking for more files.
101 ; Carry will NOT be set in this case.
102 ; DS preserved, others destroyed
107 procedure DOS_DELETE
,NEAR
108 DOSAssume
CS,<DS>,"DOS_Delete"
113 ; invoke OWN_SHARE2 ;IFS. IFS owns share ? ;AN000;
114 ; JZ ifsshare ;IFS. yes ;AN000;
115 ; PUSH WORD PTR [DMAADD+2] ;IFS. save DMAADD ;AN000;
116 ; PUSH WORD PTR [DMAADD] ;IFS. ;AN000;
117 ; CALL IFS_SEARCH_FIRST ;IFS. do search first ;AN000;
118 ; JC nofiles ;IFS. file not existing ;AN000;
119 delete_next_file: ;IFS. ;AN000;
120 ; CALL IFS_REN_DEL_CHECK ;IFS. do REN_DEL_CHECK ;AN000;
121 ; JNC share_okok ;IFS. share ok ;AN000;
122 ; MOV AX,error_sharing_violation ;IFS. share violation ;AN000;
123 ; JMP SHORT nofiles ;IFS. ;AN000;
125 ; MOV AX,(multNET SHL 8) OR 19 ;IFS. delete it now ;AN000;
126 ;; INT 2FH ;IFS. ;AN000;
127 ; JC nofiles ;IFS. error ;AN000;
128 ; invoke DOS_SEARCH_NEXT ;IFS. get next entry ;AN000;
129 ; JNC delete_next_file ;IFS. ;AN000;
130 ; CLC ;IFS. no more files ;AN000;
132 ; POP WORD PTR [DMAADD] ;IFS. retor DMAADD ;AN000;
133 ; POP WORD PTR [DMAADD+2] ;IFS. ;AN000;
141 MOV AX,(multNET
SHL 8) OR 19
147 MOV [FoundDel
],00 ; No files found and no files deleted
149 MOV WORD PTR [CREATING
],0E500H ; Assume not del *.*
154 JNZ SKPNUL
; go to end
155 SUB SI,4 ; Back over possible "*.*"
156 CMP WORD PTR [SI],("." SHL 8 OR "*")
158 CMP BYTE PTR [SI+2],"*"
161 SUB SI,9 ; Back over possible "????????.???"
165 MOV CX,4 ; four sets of "??"
170 CMP AX,("?" SHL 8) OR "."
176 MOV AL,BYTE PTR [SATTRIB
]
177 AND AL,attr_hidden
+attr_system
+attr_directory
+attr_volume_id
+attr_read_only
178 ; Look only at hidden bits
179 CMP AL,attr_hidden
+attr_system
+attr_directory
+attr_volume_id
+attr_read_only
183 ; NOTE WARNING DANGER-----
184 ; This DELALL stuff is not safe. It allows directories to be deleted.
185 ; It should ONLY be used by FORMAT in the ROOT directory.
188 MOV [DELALL
],0 ; DEL *.* - flag deleting all
198 MOV AX,error_file_not_found
205 MOV AX,error_path_not_found
209 JNZ NOT_DIR
; Check for dir specified
210 CMP DelAll
,0 ; DelAll = 0 allows delete of dir.
213 MOV AX,error_access_denied
217 OR AH,AH ; Check if device name
218 JS Del_access_err
; Can't delete I/O devices
220 ; Main delete loop. CURBUF+2:BX points to a matching directory entry.
223 OR [FoundDel
],fileFound
; file found, not deleted yet
225 ; If we are deleting the Volume ID, then we set VOLUME_CHNG flag to make
226 ; DOS issue a build BPB call the next time this drive is accessed.
232 ;; Extended Attributes
233 ; PUSH AX ;FT. save cluster of XA ;AN000;
234 ; MOV AX,DS:[BX.dir_ExtCluster];FT. ;AN000;
235 ; MOV [Del_ExtCluster],AX ;FT. ;AN000;
236 ; POP AX ;FT, ;AN000;
238 ;; Extended Attributes
239 TEST [Attrib
],attr_read_only
; are we deleting RO files too?
241 TEST DS:[BX.dir_attr
],attr_read_only
242 JZ DoDelete
; not read only
244 JMP SHORT DelNxt
; Skip it (Note ES:BP not set)
247 call REN_DEL_Check
; Sets ES:BP = [THISDPB]
250 JMP SHORT DelNxt
; Skip it
253 Assert ISBUF
,<DS,DI>,"Del_Share_OK"
254 TEST [DI.buf_flags
],buf_dirty
;LB. if already dirty ;AN000;
255 JNZ yesdirty
;LB. don't increment dirty count ;AN000;
256 invoke INC_DIRTY_COUNT
;LB. ;AN000;
257 OR [DI.buf_flags
],buf_dirty
259 MOV [BX],AH ; Put in E5H or 0
260 MOV BX,[SI] ; Get firclus pointer
262 DOSAssume
CS,<DS>,"Del_Share_OK"
263 OR [FoundDel
],fileDeleted
; Deleted file
265 JB DELEXT
; File has invalid FIRCLUS (too small)
266 CMP BX,ES:[BP.dpb_max_cluster
]
267 JA DELEXT
; File has invalid FIRCLUS (too big)
269 CALL Delete_FSeek
; delete the fastseek entry
272 invoke RELEASE
; Free file data
276 CALL FastOpen_Delete
; delete the dir info in fastopen
280 ;; Extended Attributes
283 ; MOV BX,[Del_ExtCluster] ;FT. delete XA cluster chain ;AN000;
284 ; CMP BX,2 ;FT. ;AN000;
285 ; JB DELNXT ;FT. XA has invalid cluster (too small) ;AN000;
286 ; CMP BX,ES:[BP.dpb_max_cluster];FT. ;AN000;
287 ; JA DELNXT ;FT. XA has invalid cluster (too big) ;AN000;
288 ; invoke RELEASE ;FT. Free extended attrs cluster ;AN000;
289 ; JC No_fileJ ;FT. ;AN000;
291 ;; Extended Attributes
293 LES BP,[THISDPB
] ; Possible to get here without this set
294 invoke GETENTRY
; Registers need to be reset
304 LES BP,[THISDPB
] ; NEXTENT sets ES=DOSGROUP
305 MOV AL,ES:[BP.dpb_drive
]
309 ; Now we need to test FoundDel for our flags. The cases to consider are:
311 ; not found not deleted file not found
312 ; not found deleted *** impossible ***
313 ; found not deleted access denied (read-only)
314 ; found deleted no error
316 TEST FoundDel
,fileDeleted
; did we delete a file?
317 JZ DelError
; no, figure out what's wrong.
318 ; We set VOLCHNG_FLAG to indicate that we have changed the volume label
319 ; and to force the DOS to issue a media check.
320 TEST [Attrib
],attr_volume_id
327 MOV AH,BYTE PTR ES:[DI] ; Get drive
328 SUB AH,'A' ; Convert to 0-based
329 mov byte ptr [VOLCHNG_FLAG
],AH
330 XOR BH,BH ;>32mb delte volume id from boot record ;AN000;
331 invoke Set_Media_ID
;>32mb set voulme id to boot record ;AN000;
332 invoke FATRead_CDS
; force media check
337 LeaveCrit critDisk
; carry is clear
340 TEST FoundDel
,fileFound
; not deleted. Did we find file?
341 JNZ Del_access_errJ
; yes. Access denied
349 Break <REN_DEL_Check
- check for access for rename
and delete
>
353 ; [CURBUF+2]:BX points to entry
354 ; [CURBUF+2]:SI points to firclus field of entry
355 ; [WFP_Start] points to name
357 ; Check for Exclusive access on given file.
358 ; Used by RENAME, SET_FILE_INFO, and DELETE.
361 ; NOTE: The WFP string pointed to by [WFP_Start] Will be Modified. The
362 ; last element will be loaded from the directory entry. This is
363 ; so the name given to the sharer doesn't have any meta chars in
365 ; Carry set if sharing violation, INT 24H generated
366 ; NOTE THAT AX IS NOT error_sharing_violation.
367 ; This is because input AX is preserved.
368 ; Caller must set the error if needed.
371 ; AX,DS,BX,SI,DI preserved
373 procedure REN_DEL_Check
,NEAR
374 ASSUME
DS:NOTHING
,ES:NOTHING
380 PUSH SI ; Save CURBUF pointers
383 MOV DI,[WFP_START
] ; ES:DI -> WFP
385 MOV DS,WORD PTR [CURBUF
+2] ; DS:SI -> entry (FCB style name)
386 MOV BX,DI ; Set backup limit for skipback
387 ADD BX,2 ; Skip over d: to point to leading '\'
388 invoke StrLen
; CX is length of ES:DI including NUL
389 DEC CX ; Don't include nul in count
390 ADD DI,CX ; Point to NUL at end of string
391 invoke SkipBack
; Back up one element
392 INC DI ; Point to start of last element
393 MOV [SAVE_BX
],DI ;IFS. save for DOS_RENAME ;AN000;
394 invoke PackName
; Transfer name from entry to ASCIZ tail.
395 POP SI ; Get back entry pointers
398 PUSH SI ; Back on stack
402 ; Close the file if possible by us.
409 MOV WORD PTR [THISSFT
+2],DS
410 MOV WORD PTR [THISSFT
],OFFSET DOSGROUP
:AUXSTACK
- (SIZE sf_entry
)
412 XOR AH,AH ; Indicate file to DOOPEN (high bit off)
413 invoke DOOPEN
; Fill in SFT for share check
415 MOV ES:[DI.sf_mode
],sharing_deny_both
; requires exclusive access
416 MOV ES:[DI.sf_ref_count
],1 ; Pretend open
420 MOV ES:[DI.sf_ref_count
],0 ; Pretend closed and free
421 invoke SHAREEND
; Tell sharer we're done with THISSFT
432 EndProc REN_DEL_Check
434 Break <FastOpen_Delete
- delete dir info
in fastopen
>
439 ; Call FastOpen to delete the dir info.
445 procedure FastOpen_Delete
,NEAR
446 ASSUME
DS:NOTHING
,ES:NOTHING
448 PUSH SI ; save registers
452 MOV SI,[WFP_Start
] ; ds:si points to path name
453 MOV AL,FONC_delete
; al = 3
455 MOV BX,OFFSET DOSGROUP
:FastTable
+ 2
456 CALL DWORD PTR [BX] ; call fastopen
458 POP AX ; restore registers
463 EndProc FastOpen_Delete
466 Break <FastOpen_Update
- update dir info
in fastopen
>
469 ; DL drive number (A=0,B=1,,,)
471 ; AH 0 updates dir entry
472 ; 1 updates CLUSNUM , BP = new CLUSNUM
473 ; ES:DI directory entry
475 ; Call FastOpen to update the dir info.
481 procedure FastOpen_Update
,NEAR
482 ASSUME
DS:NOTHING
,ES:NOTHING
488 MOV AL,FONC_update
; al = 4
491 EndProc FastOpen_Update
493 Break <FastSeek_Open
- create a
file extent cache
entry>
496 ; DL drive number (0=A,1=B,,,)
499 ; Create a file extent cache entry
505 procedure FastSeek_Open
,NEAR ;AN000;
506 ASSUME
DS:NOTHING
,ES:NOTHING
;AN000;
508 TEST [FastSeekflg
],Fast_yes
; Fastseek installed ? ;AN000;
509 JZ fs_no11
; no ;AN000;
510 PUSH SI ; save regs ;AN000;
512 MOV AL,FSEC_open
; al = 11 ;AN000;
514 CALL FSeek_dispatch
; call fastseek ;AN000;
515 POP AX ; restore regs ;AN000;
518 return
; return ;AN000;
519 EndProc FastSeek_Open
;AN000;
529 procedure FSeek_dispatch
,NEAR
530 ASSUME
DS:NOTHING
,ES:NOTHING
;AN000;
532 MOV AH,FastSeek_ID
; fastseek ID = 1 ;AN000;
533 entry Fast_Dispatch
; future fastxxxx entry ;AN000;
534 PUSH AX ; save ax ;AN000;
535 MOV AL,AH ; al=fastseek ID ;AN000;
538 SHL AX,1 ; times 4 to get entry offset ;AN000;
541 MOV SI,OFFSET DOSGROUP
:FastTable
+ 2 ; index to the ;AN000;
542 ADD SI,AX ; fastxxxx entry ;AN000;
543 POP AX ; restore ax ;AN000;
544 CALL DWORD PTR CS:[SI] ; call fastseek ;AN000;
546 EndProc FSeek_dispatch
548 Break <FastSeek_Close
- close a
file extent
entry>
551 ; DL drive number (0=A,1=B,,,)
554 ; Close a file extent entry
560 procedure FastSeek_Close
,NEAR
561 ASSUME
DS:NOTHING
,ES:NOTHING
;AN000;
563 TEST [FastSeekflg
],Fast_yes
; Fastseek installed ? ;AN000;
564 JZ fs_no2
; no ;AN000;
565 PUSH SI ; save regs ;AN000;
567 MOV AL,FSEC_close
; al = 12 ;AN000;
568 JMP fseek_disp
; call fastseek ;AN000;
569 EndProc FastSeek_Close
;AN000;
571 Break <FastSeek_Delete
- delete a
file extent
entry>
574 ; DL drive number (0=A,1=B,,,)
577 ; Delete a file extent entry
583 procedure FastSeek_Delete
,NEAR
584 ASSUME
DS:NOTHING
,ES:NOTHING
;AN000;
586 TEST [FastSeekflg
],Fast_yes
; Fastseek installed ? ;AN000;
587 JZ fs_no2
; no ;AN000;
588 PUSH SI ; save regs ;AN000;
590 MOV AL,FSEC_delete
; al=13 ;AN000;
591 JMP fseek_disp
; call fastseek ;AN000;
592 EndProc FastSeek_Delete
;AN000;
595 ; FastSeekflg= 0 , not installed
597 ; BX= first cluster number
598 ; ES:BP = addr of DPB
600 ; Delete a file extent entry
605 procedure Delete_FSeek
,NEAR ;AN000;
606 ASSUME
DS:NOTHING
,ES:NOTHING
;AN000;
607 TEST [FastSeekflg
],Fast_yes
; Fastseek installed ? ;AN000;
608 JZ fs_no2
; no ;AN000;
609 PUSH CX ; save regs ;AN000;
611 MOV CX,BX ; first cluster # ;AN000;
612 MOV DL,ES:[BP.dpb_drive
] ; drive # ;AN000;
613 CALL FastSeek_Delete
; call fastseek to delete an entry ;AN000;
614 POP DX ; restore regs ;AN000;
617 return
; exit ;AN000;
618 EndProc Delete_FSeek
;AN000;
620 Break <FastSeek_Lookup
- look up a cluster number
>
623 ; FSeek_drive : drive number (0=A,1=B,,,)
624 ; FSeek_firclus: first cluster #
625 ; FSeek_logclus: logical cluster #
627 ; Look up a physical cluster #
629 ; carry clear, DI = physical cluster #, FSeek_logsave=DI-1
631 ; partially found, DI=last physical cluster #
632 ; FSeek_logsave=last logical cluster #
634 procedure FastSeek_Lookup
,NEAR ;AN000;
635 ASSUME
DS:NOTHING
,ES:NOTHING
;AN000;
637 PUSH AX ; save ax ;AN000;
638 MOV AL,FSEC_lookup
; al = 14 ;AN000;
639 PUSH BX ; save bx ;AN000;
640 CALL FS_doit
; call fastseek ;AN000;
641 MOV [FSeek_logsave
],BX ; save returned BX ;AN000;
642 POP BX ; restore bx ;AN000;
643 POP AX ; restore ax ;AN000;
645 EndProc FastSeek_Lookup
;AN000;
648 Break <FastSeek_Insert
- insert a cluster number
>
651 ; FSeek_drive : drive number (0=A,1=B,,,)
652 ; FSeek_firclus: first cluster #
653 ; FSeek_logclus: logical cluster #
654 ; DI: physical cluster # to be inserted
656 ; insert a physical cluster #
661 procedure FastSeek_Insert
,NEAR
662 ASSUME
DS:NOTHING
,ES:NOTHING
664 TEST [FastSeekflg
],FS_insert
; insert mode set ? ;AN000;
665 JZ no_insert
; no ;AN000;
667 PUSH AX ; save regs ;AN000;
669 MOV AL,FSEC_insert
; al = 15 ;AN000;
671 CALL FS_doit
; call fastseek ;AN000;
672 POP BX ; restore regs ;AN000;
676 EndProc FastSeek_insert
678 Break <FastSeek_Truncate
- truncate cluster numbers
>
681 ; FSeek_drive : drive number (0=A,1=B,,,)
682 ; FSeek_firclus: first cluster #
683 ; FSeek_logclus: logical cluster #
685 ; truncate physical cluster #s starting from FSeek_logclus
690 procedure FastSeek_Truncate
,NEAR
691 ASSUME
DS:NOTHING
,ES:NOTHING
693 TEST [FastSeekflg
],Fast_yes
; Fastseek installed ? ;AN000;
694 JZ fs_no
; no ;AN000;
695 PUSH AX ; save regs ;AN000;
697 MOV AL,FSEC_truncate
; al = 16 ;AN000;
698 JMP FSentry
; call fastseek ;AN000;
701 EndProc FastSeek_Truncate
;AN000;
704 ; FSeek_drive : drive number (0=A,1=B,,,)
705 ; FSeek_firclus: first cluster #
706 ; FSeek_logclus: logical cluster #
708 ; set up parameters and call fastseek
710 ; outputs of fastseek
712 procedure FS_doit
,NEAR
713 ASSUME
DS:NOTHING
,ES:NOTHING
715 PUSH CX ; save regs ;AN000;
718 MOV DL,[FSeek_drive
] ; set drive # ;AN000;
719 MOV CX,[FSeek_firclus
] ; set 1st cluster # ;AN000;
720 MOV BX,[FSeek_logclus
] ; set logical cluster # ;AN000;
722 CALL FSeek_dispatch
; call fastseek ;AN000;
724 ; carry clear if found in DI ;AN000;
725 POP SI ; otherwise, carry set ;AN000;
727 POP DX ; restore regs ;AN000;
730 EndProc FS_doit
;AN000;
734 ; same as DOS_SEARCH_FIRST
736 ; do a IFS search first
738 ; same as DOS_SEARCH_FIRST
740 procedure IFS_SEARCH_FIRST
,NEAR ;AN000;
741 DOSAssume
CS,<DS>,"IFS_SEARCH_FIRST" ;AN000;
742 ASSUME
ES:NOTHING
;AN000;
744 ; MOV WORD PTR [DMAADD+2],DS ;IFS. replace with scratch area ;AN000;;AN000;
745 ; MOV WORD PTR [DMAADD],OFFSET DOSGROUP:RENAMEDMA ;IFS. ;AN000;
746 ; invoke SET_THISDPB ;IFS. THISDPB set ;AN000;
747 ; invoke DOS_SEARCH_FIRST ;IFS. search first ;AN000;
749 EndProc IFS_SEARCH_FIRST
;AN000;
754 ; WFP_Start points to name
756 ; do a IFS REN_DEL_CHECK
758 ; same as REN_DEL_CHECK
760 procedure IFS_REN_DEL_CHECK
,NEAR ;AN000;
761 DOSAssume
CS,<DS>,"IFS_REN_DEL_CHECK" ;AN000;
762 ASSUME
ES:NOTHING
;AN000;
764 ; MOV AX,WORD PTR [DMAADD+2] ;IFS. set up ;AN000;;AN000;
765 ; MOV WORD PTR [CURBUF+2],AX ;IFS. curbuf+2 : bx -> dir entry ;AN000;
766 ; MOV BX,WORD PTR [DMAADD] ;IFS. ;AN000;
767 ; ADD BX,21 ;IFS. ;AN000;
768 ; MOV SI,BX ;IFS. curbuf+2:si -> dir_first ;AN000;
769 ; ADD SI,dir_first ;IFS. ;AN000;
770 ; EnterCrit critDisk ;IFS. enter critical section ;AN000;
771 ; CALL REN_DEL_Check ;IFS. share check ;AN000;
772 ; LeaveCrit critDisk ;IFS. leave critical section ;AN000;
774 EndProc IFS_REN_DEL_CHECK
;AN000;