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

📄 gshare2.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	Title	Share_2

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

;
;	Revision History
;	================
;
;	M000	SR	08/03/90	Fixed ShComndParse so that it exits
;					after displaying help text on a 
;					Share /?
;
;	M001	SR	9/10/90	Removed all /NC support from the code
;				and rewrote the init code to not use
;				all the special Share int 2fh calls.
;
;	M002	SR	9/26/90	Bug #3013. The installed message and
;				parse error message had identical
;				message numbers. Also check the class.
;
; 	M004	HKN	10/18/90	To determine whether the SFT is a
;					net SFT or a device we must check
;					the sf_flags. bug #3584
;
;	M005	SR	10/16/90	Bug #2914. Changed to ignore the /NC
;				switch instead of making it an
;				invalid switch.
;
;	M006	SR	10/22/90	Bug #3583. Changed parsing to check
;				for multiple occurrences of a switch
;				and give out an error message. Share
;				still continues to load and uses the
;				parameter value first specified.
;
;	M007	SR	11/16/90	Bug #4240. Added check to ShareInit
;				to look for switcher and fail to load
;				if switcher is present.
;



	include SHAREHDR.INC
;
;     Label: "The DOS SHARE Utility"
;
;******************* END OF SPECIFICATIONS *************************************


				   NAME Sharer2

					   ;  INCLUDE DOSSYM.INC
					   ;  INCLUDE SYSMSG.INC
				   .xlist
				   .xcref
				   INCLUDE DOSSYM.INC
				   INCLUDE SYSMSG.INC
					include filemode.inc
					include arena.inc
					include cpmfcb.inc
					include sf.inc
					include pdb.inc
					include sysvar.inc
					include syscall.inc
					include mult.inc
					include version.inc
					include vector.inc
					include int2a.inc
				   .cref
				   .list
				   page 80,132

				   MSG_UTILNAME <SHARE>

ShareDataVersion		   =	1

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
					   ;---------------------------------------
;	$SALUT	(4,9,17,36)

	IF	Installed

	    Share   SEGMENT BYTE PUBLIC 'SHARE'
	    Share   ENDS
	include dosseg.inc
	ENDIF

				   ;---------------------------------------
				   ; include the rest of the segment
				   ;  definitions for normal msdos

				   ; segment ordering for MSDOS

				   ;---------------------------------------


	DOSDATA SEGMENT

	extrn	DataVersion:BYTE   ; version number of DOS data.
	extrn	JShare:BYTE	   ; location of DOS jump table.
	extrn	sftFCB:DWORD	   ; [SYSTEM] pointer to FCB cache table
	extrn	KeepCount:WORD	   ; [SYSTEM] LRU count for FCB cache
	extrn	CurrentPDB:WORD

	extrn	ThisSFT:DWORD	   ; pointer to SFT entry
	extrn	WFP_start:WORD	   ; pointer to name string
	extrn	User_ID:WORD
	extrn	Proc_ID:WORD
	extrn	SFT_addr:DWORD
	extrn	Arena_Head:WORD
	extrn	fshare:BYTE
	extrn	pJFN:DWORD
	extrn	JFN:WORD

	IF	DEBUG

	    extrn   BugLev:WORD
	    extrn   BugTyp:WORD
	    include bugtyp.inc

	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:DOSCODE

	ELSE

	    Share   SEGMENT BYTE PUBLIC 'SHARE'

	    ASSUME  SS:DOSDATA,CS:SHARE

	ENDIF



	Extrn	FreLock:WORD,Serial:WORD
	Extrn	MFT_Enter:NEAR,MFTClose:NEAR,MFTClu:NEAR,MFTCloseP:NEAR
	Extrn	MFTCloN:NEAR
	Extrn	Set_Mult_Block:NEAR,Clr_Mult_Block:NEAR,Chk_Block:NEAR
	Extrn	MFT_Get:NEAR

	include mft.inc

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

   BREAK <FNM - Find name in MFT>

;******************* START OF SPECIFICATIONS ***********************************
;
;	FNM - Find name in MFT
;
;	FNM searches the MFT for a name record.
;
;	ENTRY	(DS:SI) = pointer to name string (.asciz)
;		(al) = 1 to create record if non exists
;		     = 0 otherwise
;	EXIT	'C' clear if found or created
;		  (DS:BX) = address of MFT name record
;		'C' set if error
;		  If not to create, item not found
;		    (DS:SI) unchanged
;		  If to create, am out of space
;		    (ax) = error code
;	USES	ALL
;
;******************* END OF SPECIFICATIONS *************************************

   Procedure FNM,NEAR

   push ds				; save string address
   push si
   xchg bh,al				; (bh) = create flag
   or	bh,bh				; if not creating
   jz	fnm01				; skip sft test

					;---------------------------------------
					; run down through string counting
					;  and summing
					;---------------------------------------

fnm01: sub dx,dx			; (dx) = byte count
   sub	bl,bl				; (bl) = sum

fnm1: lodsb				; (al) = next char
   add	bl,al
   adc	bl,0
   inc	dx
   and	al,al
   jnz	fnm1				; terminate after null char

					;---------------------------------------
					; Info computed.
					;  Start searching name list

					;  (bh) = create flag
					;  (bl) = sum byte
					;  (dx) = byte count
					;  (TOS+2:TOS) = name string address
					;---------------------------------------
   push cs
   pop	ds

   Off	SI,mft

fnm2: cmp [si].mft_flag,MFLG_FRE
   jl	fnm10				; at end - name not found
   jz	fnm4				; is free, just skip it
   cmp	bl,[si].mft_sum 		; do sums compare?
   jz	fnm5				; its a match - look further
fnm4: add si,[si].mft_len		; not a match... skip it
   JMP	SHORT fnm2
					;---------------------------------------
					; name checksums match
					;   - compare the actual strings
					;
					;   (dx)	= length
					;   (ds:si	= MFT address
					;   (bh)	= create flag
					;   (bl)	= sum byte
					;   (dx)	= byte count
					;   (TOS+2:TOS) = name string address
					;---------------------------------------

fnm5: mov cx,dx 			; (cx) = length to match
   pop	di
   pop	es				; (ES:DI) = fba given name
   push es
   push di
   push si				; save MFT offset
   add	si,mft_name			; (ds:si) = fwa string in record
   repz cmpsb
   pop	si				; (ds:si) = fwa name record
   jnz	fnm4				; not a match

					;---------------------------------------
					; Yes, we've found it.  Return the info
					;
					;  (TOS+2:TOS) = name string address
					;---------------------------------------

   fmt	TypShare,LevMFTSrch,<"FNM found name record at $x\n">,<si>
   pop	ax				; discard unneeded stack stuff
   pop	ax
   mov	bx,si				; (ds:bx) = fwa name record
   clc

   ret
					;---------------------------------------
					;**
					;**  Its not in the list
					;**  - lets find a free spot and put
					;**    it there
					;
					;  (bh)        = create flag
					;  (bl)        = sum byte
					;  (dx)        = string length
					;  (TOS+2:TOS) = ASCIZ string address
					;  (ds)        = SEG CODE
					;---------------------------------------
fnm10:
   and	bh,bh
   jnz	fnm10$5 			; yes, insert it
   pop	si
   pop	ds				; no insert, its a "not found"
   stc

   fmt	TypShare,LevMFTSrch,<"FNM failing\n">

   mov	ax,error_path_not_found

   ret

fnm10$5:
   add	dx,mft_name			; (dx) = minimum space needed

   off	SI,mft

fnm11: cmp [si].mft_flag,MFLG_FRE

   IF	NOT  DEBUG
       jl   fnm20			; at END, am out of space
   ELSE
       jl   fnm20j
   ENDIF

   jz	fnm12				; is a free record
   add	si,[si].mft_len 		; skip name record
   JMP	SHORT fnm11

   IF	DEBUG
fnm20j: jmp fnm20
   ENDIF

fnm12: mov ax,[si].mft_len		; Have free record, (ax) = total length
   cmp	ax,dx
   jnc	fnm13				; big enough
   add	si,ax
   JMP	SHORT fnm11			; not large enough - move on

					;---------------------------------------
					; OK, we have a record which is big
					;  enough.  If its large enough to hold
					;  another name record of 6 characters
					;  than we'll split the block, else
					;  we'll just use the whole thing
					;
					; (ax)	      = size of free record
					; (dx)	      = size needed
					; (ds:si)     = address of free record
					; (bl)	      = sum byte
					; (TOS+2:TOS) = name string address
					;---------------------------------------

fnm13: sub ax,dx			; (ax) = total size of proposed fragment
   cmp	ax,mft_name+6
   jc	fnm14				; not big enough to split
   push bx				; save sum byte
   mov	bx,dx				; (bx) = offset to start of new name record
   mov	[bx][si].mft_flag,MFLG_FRE
   mov	[bx][si].mft_len,ax		; setup tail as free record
   sub	ax,ax				; don't extend this record
   pop	bx				; restore sum byte
fnm14: add dx,ax			; (dx) = total length of this record
   mov	[si].mft_len,dx
   mov	[si].mft_sum,bl
   mov	[si].mft_flag,MFLG_NAM

   fmt	TypShare,LevMFTSrch,<"FNM creating record at $x\n">,<si>

   push ds
   pop	es				; (es) = MFT segment for "stow"
   sub	ax,ax
   mov	di,si
   add	di,mft_lptr
   stosw				; zero LCK pointer
   ERRNZ mft_sptr-mft_lptr-2
;	add	di,mft_sptr-mft_lptr-2
   stosw				; zero SFT pointer
   stosw				; zero SFT pointer
   inc	serial				; bump serial number
   mov	ax,serial
   ERRNZ mft_serl-mft_sptr-4
;	ADD	di,mft_serl-mft_sptr-4
   stosw
					;---------------------------------------
					; We're all setup except for the name.
					;  Note that we'll block copy the whole
					;  name field, even though the name may
					;  be shorter than that (we may have
					;  declined to fragment this memory block)
					;
					;	(dx) = total length of this record
					;	(ds:si) = address of working record
					;	(es) = (ds)
					;	(TOS+2:TOS) = name string address
					;---------------------------------------
   mov	cx,dx
   sub	cx,mft_name			; compute total size of name area
   ERRNZ mft_name-mft_serl-2
;	add	di,mft_name-mft_serl-2	; (ES:DI) = target address
   mov	ax,si				; save name record offset
   pop	si
   pop	ds
   rep	movsb
   mov	bx,ax				; (bx) = name record offset
   push es
   pop	ds				; (DS:BX) = name record offset
   clc

   ret

;**
;**	OUT OF FREE SPACE
;**
;**	This is tough, folks.  Lets trigger a garbage collection and see if
;**	there is enough room.  If there is, we'll hop back and relook for a
;**	free hunk; if there isnt enough space, its error-city!
;
;	WARNING: it is important that the garbage collector be told how big a
;		name record hole we're looking for...  if the size given GCM
;		is too small we'll loop doing "no space; collect; no space;
;		...)
;
;	(dx) = total length of desired name record
;	(ds) = SEG CODE
;	(bl) = sum byte
;	(TOS+2:TOS) = name string address

fnm20:
   mov	ax,dx				; (ax) = size wanted
   sub	dx,mft_name			; (dx) = string length for reentry at fnm10
   push dx
   push bx
   call GCM				; garbage collect MFT
   pop	bx
   pop	dx

   IF	DEBUG
       jnc  fnm10j
   ELSE
       jnc  fnm10			; go back and find that space
   ENDIF

					;---------------------------------------
					; no space, return w/error
					;---------------------------------------

fnm50: pop ax
   pop	ax				; clean stack
   mov	ax,error_sharing_buffer_exceeded
   stc

   ret

   IF	DEBUG
fnm10j: jmp fnm10
   ENDIF

   EndProc FNM

   BREAK <GCM - Garbage Collect MFT>

;******************* START OF SPECIFICATIONS ***********************************
;
;	GCM - Garbage Collect MFT
;
;	GCM runs down the MFT structure squeezing out the free space and
;	putting it into one free block at the end.  This is a traditional heap
;	collection process.  We must be sure to update the pointer in the
;	SFTs.  This presumes no adjacent free blocks.
;
;	ENTRY	(ax) = space desired in last free block
;		(DS) + SEG CODE
;	EXIT	'C' clear if enough space in block
;		'C' set if not enough space
;
;******************* END OF SPECIFICATIONS *************************************

   Procedure GCM,NEAR

   push ax				; save target
   off	si,mft				; (si) = from pointer
   mov	di,si				; (di) = to pointer

					;---------------------------------------
					; (DI) points to the beginning of
					;	a free space block
					; (SI) points to the next block.
					;---------------------------------------

gcm1: mov cx,[si].mft_len		; (cx) = size of whatever it is
   cmp	[si].mft_flag,MFLG_FRE
   jl	gcm10				; END marker
   jnz	gcm2				; have a name record

⌨️ 快捷键说明

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