⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gshare.asm

📁 DOS 源代码 系列之 command 源码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	Title	Share_1

;/*
; *                      Microsoft Confidential
; *                      Copyright (C) Microsoft Corporation 1991
; *                      All Rights Reserved.
; */

;				   $SALUT (0,36,41,44)
				   include SHAREHDR.INC
;
;     Label: "The DOS SHARE Utility"
;
;******************* END OF SPECIFICATIONS *************************************

;
;	Revision History
;	================
;
;	M001	SR	9/10/90	Removed /NC support -- 'skip_check'
;				references.
;
;	M003	SR	10/1/90	Bug #2425 fixed. In ASC, check if the
;				SFT to be chained is the same as the
;				current SFT. Dont chain if so.
;



extrn				   fnm:near, rsc:near, rmn:near, cps:near, ofl:near, sle:near, interr:near

				   NAME Sharer

				   .xlist
				   .xcref
					include sf.inc
					include filemode.inc
					include mult.inc
					include syscall.inc
				   INCLUDE DOSSYM.INC
				   include dpl.asm
				   .cref
				   .list

AsmVars 			   <IBM, Installed>

Installed			   =	TRUE ; for installed version

OFF				   Macro reg,val
				   IF	installed
				   mov	reg,OFFSET val
				   ELSE
				   mov	si,OFFSET DOSGROUP:val
				   ENDIF
				   ENDM

ERRNZ				   Macro x
				   IF	x NE 0
				   %out ERRNZ failed
				   ENDIF
				   ENDM
; if we are installed, then define the base code segment of the sharer first

				   IF	Installed
Share				   SEGMENT PARA PUBLIC 'SHARE'
Share				   ENDS

	include dosseg.inc

;  include the rest of the segment definitions for normal msdos
; We CANNOT include dosseg because start is not declared para in that file

;	$SALUT	(4,9,17,36)

;START	 SEGMENT PARA PUBLIC 'START'
;START	 ENDS

;CONSTANTS SEGMENT WORD PUBLIC 'CONST'
;CONSTANTS ENDS

;DATA	 SEGMENT WORD PUBLIC 'DATA'
;DATA	 ENDS

;TABLE	 SEGMENT BYTE PUBLIC 'TABLE'
;TABLE	 ENDS

;CODE	 SEGMENT BYTE PUBLIC 'CODE'
;CODE	 ENDS

;LAST_SEG    SEGMENT PARA PUBLIC 'LAST_SEG'
;LAST_SEG    ENDS

;DOSGROUP GROUP  START,CONSTANTS,DATA,TABLE,CODE,LAST_SEG
	ELSE
	include dosseg.asm
	ENDIF

DOSDATA    SEGMENT WORD PUBLIC 'DATA'
	Extrn	ThisSFT:DWORD	   ; pointer to SFT entry
	Extrn	User_ID:WORD
	Extrn	Proc_ID:WORD
	Extrn	WFP_START:WORD
	Extrn	BytPos:DWORD
	extrn	OpenBuf:BYTE
	extrn	user_in_ax:WORD
	IF	debug
	    Extrn   BugLev:WORD
	    Extrn   BugTyp:WORD
	    include bugtyp.asm
	ENDIF
DOSDATA    ENDS

;   if we are not installed, then the code here is just part of the normal
;   MSDOS code segment otherwise, define our own code segment

	.sall
	IF	NOT INSTALLED
CODE	    SEGMENT BYTE PUBLIC 'CODE'
	    ASSUME  SS:DOSGROUP,CS:DOSGROUP
	ELSE
Share	    SEGMENT PARA PUBLIC 'SHARE'
	    ASSUME  SS:DOSDATA,CS:SHARE
	ENDIF

	extrn	MFT:BYTE
;SR;
; This message is now defined in another file for internationalization
;purposes.
;
	extrn	AscErr:BYTE

	include mft.inc

	PUBLIC	FreLock,Serial

	IF	installed
Frelock     DW	    ?		   ; FWA of lock free list
	ELSE
Frelock     DW	    OFFSET DOSDATA:lck8 ; FWA of lock free list
	ENDIF
Serial	DW	0		   ; serial number
DS_Org	dw	0		   ;an000;DS on entry to routine

ZERO	EQU	0
ONE	EQU	1

FRAME	struc

SavedBP dw	?
RetOFF	dw	?
Parm_1	dw	?
Parm_2	dw	?

FRAME	ends

;  $SALUT (4,4,9,41)

   BREAK <Sharer - MultiProcess File Sharer>

;******************* START OF SPECIFICATIONS ***********************************
;
;	MSDOS MFT Functions
;
;	The Master File Table (MFT) associates the cannonicalized pathnames,
;	lock records and SFTs for all files open on this machine.
;
;	These functions are supplied to maintain the MFT and extract
;	information from it.  All MFT access should be via these routines so
;	that the MFT structure can remain flexible.
;
;******************* END OF SPECIFICATIONS *************************************

   BREAK <Mft_enter - Make an MFT entry and check access>

;******************* START OF SPECIFICATIONS ***********************************
;
;	mft_enter - make an entry in the MFT
;
;	mft_enter is called to make an entry in the MFT.
;	mft_enter checks for a file sharing conflict:
;		No conflict:
;		    A new MFT entry is created, or the existing one updated,
;		    as appropriate.
;		Conflicts:
;		    The existing MFT is left alone.  Note that if we had to
;		    create a new MFT there cannot be, by definition, sharing
;		    conflicts.
;	If no conflict has been discovered, the SFT list for the file is
;	checked for one that matches the following conditions:
;
;	    If mode == 70 then
;		don't link in SFT
;		increment refcount
;	    If mode&sfIsFCB and userids match and process ids match then
;		don't link in SFT
;
;	ENTRY	ThisSFT points to an SFT structure.  The sf_mode field
;		    contains the desired sharing mode.
;		WFP_Start is an offset from DOSData of the full pathname for
;		    the file
;		User_ID = 16-bit user id of issuer
;		Proc_ID = 16-bit process id of issuer
;		(DS) = (SS) = DOSData
;	EXIT	'C' clear if no error'
;		'C' set if error
;		  (ax) = error code
;	USES	ALL but DS
;
;******************* END OF SPECIFICATIONS *************************************

   Procedure mft_enter,NEAR

;  int 3
   nop
   nop

   EnterCrit critShare

   DOSAssume SS <DS>,"MFT_Enter entry"
   ASSUME ES:NOTHING,SS:DOSDATA
   push ds

;	find or make a name record

   mov	si,WFP_Start			; (DS:SI) = FBA of file name
   mov	al,1				; allow creation of MFT entry
   push es

   ASSUME DS:NOTHING

   call FNM				; find or create name in MFT
   pop	es
   mov	ax,error_sharing_buffer_exceeded
   jc	ent9				; not enough space
;
;	(bx) = fwa name record
;
   lds	si,ThisSFT
   call ASC				; try to add to chain

;	As noted above, we don't have to worry about an "empty" name record
;	being left if ASC refuses to add the SFT - ASC cannot refuse if we had
;	just created the MFT...

;	return.
;
;	'C' and (Ax) setup appropriately

ent9: pop ds

   LeaveCrit critShare

   ret

   EndProc mft_enter

   BREAK <MftClose - Close out an MFT for given SFT>

;******************* START OF SPECIFICATIONS ***********************************
;
;	MFTclose
;
;	MFTclose(SFT)
;
;	MFTclose removes the SFT entry from the MFT structure.	If this was
;	the last SFT for the particular file the file's entry is also removed
;	from the MFT structure.  If the sharer is installed after some
;	processing has been done, the MFT field of the SFTs will be 0; we must
;	ignore these guys.
;
;	If the sft indicates FCB, we do nothing special.  The SFT behaves
;	    EXACTLY like a normal handle.
;
;	If the sft indicates mode 70 then we do nothing special.  These are
;	normal HANDLES.
;
;	Note that we always care about the SFT refcount.  A refcount of 1
;	means that the SFT is going idle and that we need to remove the sft
;	from the chain.
;
;	ENTRY	(ES:DI) points to an SFT structure
;		(DS) = (SS) = DOSData
;	EXIT	NONE
;	USES	ALL but DS, ES:DI
;
;******************* END OF SPECIFICATIONS *************************************

   Procedure MFTclose,NEAR

;  int 3
   nop
   nop

   EnterCrit critShare

   DOSAssume SS,<DS>,"MFTClose entry"
   ASSUME ES:NOTHING
   mov	ax,es:[di].sf_MFT

   fmt	TypShare,LevShEntry,<"MFTClose by $x:$x of $x:$x ($x)\n">,<User_ID,Proc_id,ES,DI,AX>

   or	ax,ax
   jz	mcl10				; No entry for it, ignore (carry clear)
   push ds
   push es
   push di
;;;call CSL				; clear SFT locks		       ;AC008;

   ASSUME DS:NOTHING

   mov	ax,es:[di].sf_ref_count 	; (ax) = ref count
;
; We need to release information in one of two spots.  First, when the SFT has
; a ref count of 0.  Here, there are no more referents and, thus, no sharing
; record need be kept.	Second, the ref count may be -1 indicating that the
; sft is being kept but that the sharing information is no longer needed.
; This occurs in creates of existing files, where we verify the allowed
; access, truncate the file and regain the access.  If the truncation
; generates an error, we do NOT want to have the access locked down.
;


   OR	AX,AX
   jz	mcl85				; ref count is 0 - don't dechain
   inc	ax				; -1 + 1 = 0.  Busy sft.
   jnz	mcl9
mcl85:
   call CSL				; clear SFT locks		       ;AC008;
   call RSC				; remove sft from chain
   jnz	mcl9				; not the last sft for this name
   call RMN				; remove name record
mcl9:
   pop	di				; restore regs for exit
   pop	es
   pop	ds
mcl10:
   LeaveCrit critShare

   ret

   EndProc MFTclose

   BREAK <MftClU - Close out all MFTs for given UID>

;******************* START OF SPECIFICATIONS ***********************************
;
;	MFTcloseU
;
;	MFTcloseM(UID)
;
;	MFTcloseM removes all entrys for user UID from the MFT structure.  We
;	    walk the MFT structure closing all relevant SFT's for the user.
;	    We do it the dumb way, iterating closes until the SF ref count is
;	    0.
;
;	ENTRY	User_ID = 16-bit user id of issuer
;		(SS) + DOSData
;	EXIT	'C' clear
;	USES	ALL
;
;******************* END OF SPECIFICATIONS *************************************

   Procedure MFTclU,NEAR

;  int 3
   nop
   nop

   ASSUME DS:NOTHING,ES:NOTHING,SS:DOSDATA

   EnterCrit critShare
   mov	ax,User_ID

   fmt	TypShare,LevShEntry,<"\nCloseUser $x\n">,<AX>

   sub	bx,bx				; insensitive to PID
   sub	dx,dx
   invoke BCS				; bulk close the SFTs
   LeaveCrit critShare
   return
   EndProc MFTclU

   BREAK <MftCloseP - Close out all MFTs for given UID/PID>

;******************* START OF SPECIFICATIONS ***********************************
;
;	MFTcloseP
;
;	MFTcloseP(PID, UID)
;
;	MFTcloseP removes all entrys for process PID on machine MID from the
;	    MFT structure.  We walk the MFT structure closing all relevant
;	    SFT's.  Do it the dumb way by iterating closes until the SFTs
;	    disappear.
;
;	ENTRY	(SS) = DOSDATA
;		User_ID = 16-bit user id of issuer
;		Proc_ID = 16-bit process id of issuer
;	EXIT	'C' clear
;	USES	ALL
;
;******************* END OF SPECIFICATIONS *************************************

   Procedure MFTcloseP,NEAR

;  int 3
   nop
   nop

   ASSUME DS:NOTHING,ES:NOTHING,SS:DOSDATA

   EnterCrit critShare
   mov	ax,User_ID
   mov	bx,-1
   mov	dx,Proc_ID

   fmt	TypShare,LevShEntry,<"\nClose UID/PID $x:$x\n">,<AX,DX>

   call BCS				; Bulk close the SFTs
   LeaveCrit critShare

   ret

   EndProc MFTcloseP

   BREAK <MftCloN - Close file by name>

;******************* START OF SPECIFICATIONS ***********************************
;
;	MFTcloseN
;
;	MFTcloseN(name)
;
;	MFTcloseN removes all entrys for the given file from the MFT
;	structure.
;
;	NOTE: this function is used infrequently and need not be fast.
;		(although for typical use it's not all that slow...)
;
;	ENTRY	DS:SI point to dpl.
;		(SS) = DOSData
;	EXIT	'C' clear if no error
;		'C' set if error
;		  AX = error_path_not_found if not currently open
;	USES	ALL
;
;******************* END OF SPECIFICATIONS *************************************

   Procedure MFTcloN,NEAR

;  int 3
   nop
   nop

   ASSUME SS:DOSDATA,ES:NOTHING,DS:NOTHING

   EnterCrit critShare
   MOV	DX,[SI.DPL_DX]
   MOV	DS,[SI.DPL_DS]
   mov	si,dx				; (DS:SI) = fwa name
   sub	al,al				; don't create if not found
   push ds
   push si
   call FNM				; find name in MFT
   mov	ax,error_path_not_found 	; assume error
   jc	mclo9				; not found exit

;	Name was found.  Lets yank the SFT entrys one at a time.

mclo1: les di,[bx].mft_sptr		; (ES:DI) = SFT address
   mov	WORD PTR ThisSFT,di
   mov	WORD PTR ThisSFT+2,es		; point to SFT
   cmp	es:[di].sf_ref_count,1
   jnz	mclo15
   call CPS
mclo15:
   Context DS

   IF	installed
       MOV  AX,(multDOS SHL 8) + 1
       INT  2FH
   ELSE
       call DOS_Close
   ENDIF
mclo2:

   ASSUME DS:NOTHING

   pop	si
   pop	ds
   push ds
   push si

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -