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

📄 gshare.asm

📁 DOS 源代码 系列之 command 源码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;      WE HAVE:   (from IBMDOS) 	|	  WE NEED:   (for Clr_Block)

; (AX)	  = 0 - lock all		|    (BX)    = 0 lock all operations
;	  = 1 - lock write		|	     = 1 lock write operations
; (CX)	  = the number of lock ranges	|    (CX:DX) = offset of area
; (DS:DX) = pointer to the range list	|    (SI:AX) = length of area
; (ES:DI) = SFT address 		|    (ES:DI) = SFT address

;;	   PUSH CX			; count = start_count		       ;AN000;
;;	   PUSH DX			; save pointer to range list	       ;AN000;
       MOV  BP,DX			; save current index into list	       ;AN000;
;;	   MOV	BX,AX			; SET UP TYPE OF LOCK		       ;AN000;

       call Clr_List			; call Clr_List to process the list    ;AN000;

;;     $ENDIF				;				       ;AN000;

;  $ELSE				; NOT VALID
   JMP SHORT $$EN6
$$IF6:

       STC				;				       ;AN000;

;  $ENDIF				; VALID/INVALID 		       ;AN000;
$$EN6:

;  $IF	C				; if carry is set		       ;AN000;
   JNC $$IF9
       MOV  AX,error_lock_violation	; load error condition		       ;AN000;
;  $ENDIF				; carry not set 		       ;AN000;
$$IF9:

   LeaveCrit critShare			;				       ;AN000;

   ret					; return - all set		       ;AN000;

   EndProc clr_mult_block

   BREAK <Clr_List - Clear a list of user specified locks>

;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:	   Clr_List  -	Clear a list of user specified locks
;
;  FUNCTION:	   Clr_List makes multiple calls to Clr_Block to clear
;		   multiple lock ranges of a file.  An error is returned
;		   if any lock range does not exactly match. Ranges of
;		   Locks are then set via Set_Mult_Block.
;
;
;  INPUT:	   (BX)    = 0 lock all operations
;			   = 1 lock write operations
;		   (CX:DX) = offset of area
;		   (SI:AX) = length of area
;		   (ES:DI) = SFT address
;		   (SS:SP+2)= original index \ see FRAME struc
;		   (SS:SP+4)= original count /
;
;  OUTPUT:	   Lock records removed for all blocks specified
;		   Stack cleard on return
;
;  REGISTERS USED: ALL but DS
;  (NOT RESTORED)
;
;  LINKAGE:	   IBMDOS Jump Table
;
;  EXTERNAL	   Invoke: Load_Regs, Set_Block, Clr_Block
;  REFERENCES:
;
;  NORMAL	   'C' clear if no error
;  EXIT:
;
;  ERROR	   'C' set if error
;  EXIT:	     (ax) = error code
;			       ('error_lock_violation' if conflicting locks)
;
;  CHANGE	04/15/87 - First release
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************+ START OF PSEUDOCODE +**************************************
;
;	START Clr_List
;
;	search till count = 0
;		set up for call
;		call clr_Block
;	exit if c
;		clear_count = start_count - current_count
;		loop till clear_count = 0
;			set up for call
;			call Set_Block
;		end loop
;		set error status
;	orelse
;	endloop
;		set successful status
;	endsrch
;	return
;
;	END Clr_List
;
;******************+  END  OF PSEUDOCODE +**************************************

   Procedure Clr_List,NEAR

;; $do					;an000;while cx not = 0
;;     cmp  cx,00			;an000;at end?
;; $leave e				;an000;yes
;;     push cx				;an000;save cx - our counter
;;     push di				;an000;save di - our SFT pointer
   call load_regs			;an000;set up for clr_block call
;;     push bp				; save pointer to range entry	       ;AN000;
   call clr_block			;an000;remove the lock
;;     pop  bp				; recover pointer to range entry       ;AN000;
;;     pop  di				;an000;restore our SFT pointer
;;     pop  cx				;an000;restore cx - our counter
;; $leave c				;an000;leave on error
;;     dec  cx				;an000;decrease counter
;; $enddo				;an000;

;; $if	c				;an000;an error occurred
;;     push bp				;an000;save bp
;;     mov  bp,sp			;an000;get sp
;;     mov  dx,[bp].parm_1		;an000;recover original index
;;     mov  ax,[bp].Parm_2		; original count		       ;AN000;
;;     pop  bp
;;     SUB  AX,CX			; how many did we do?		       ;AN000;
;;     MOV  CX,AX			; set up the loop		       ;AN000;
;;     MOV  BP,DX			; save the index		       ;AN000;

;;     $DO				;				       ;AN000;
;;	   cmp	cx,00			;an000;at end?
;;     $leave e 			;an000;yes
;;	   push cx			;an000;save cx - our counter
;;	   push di			;an000;save di - our SFT pointer
;;	   call load_regs		;an000;set up for set_block call
;;	   call set_block		;an000;reset the locks
;;	   pop	di			;an000;restore our SFT pointer
;;	   pop	cx			;an000;restore cx - our counter
;;     $leave c 			;an000;leave on error
;;	   dec	cx			;an000;decrease counter
;;     $enddo				;an000;
;;     stc				;an000;signal an error
;; $else				;an000;
;;     clc				;an000;signal no error
;; $endif				;an000;

;; ret	4				; return (clear Parm_1 & Parm_2)       ;AN000;
   ret					; return (clear Parm_1 & Parm_2)       ;AC006;

   EndProc Clr_List


   BREAK <Set_Block - Try to set a lock>

;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:	   Set_Block - set byte range lock on a file
;
;  FUNCTION:	   Set_Block sets a lock on a specified range of a file.  An
;		   error is returned if the lock conflicts with another.
;		   Locks are cleared via clr_block.
;
;  INPUT:	   (ES:DI) = SFT address
;		   (CX:DX) = offset of area
;		   (SI:AX) = length of area
;		   (BX)    = 0 lock all operations
;			   = 1 lock write operations
;		   User_ID = 16-bit user id of issuer
;		   Proc_ID = 16-bit process id of issuer
;		   (SS) = DOSData
;
;  OUTPUT:	   Lock records removed for all blocks specified
;
;  REGISTERS USED: ALL but DS, BP
;  (NOT RESTORED)
;
;  LINKAGE:	   Invoked by: Set_Mult_Block
;
;  EXTERNAL	   Invoke: CLP (SLE), OFL
;  REFERENCES:
;
;  NORMAL	   'C' clear if no error
;  EXIT:
;
;  ERROR	   'C' set if error
;  EXIT:
;
;  CHANGE	04/15/87 - lock only write support
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************+ START OF PSEUDOCODE +**************************************
;
;	START Set_Block
;
;	if a valid SFT and
;	invoke CLP
;	if no lock conflicts and
;	invoke OFL
;	if empty lock record available
;		store SFT pointer
;		store lock range
;		add RLR to the chain
;		store PROC_ID
;		store rlr_type
;		set successful return status
;	else
;		set error return status
;	endif
;	return
;
;	END Set_Block
;
;******************+  END  OF PSEUDOCODE +**************************************

   Procedure Set_Block,NEAR

   ASSUME ES:NOTHING,DS:NOTHING

   Context DS

   push bp				; preserve (bp) 		       ;AN000;
   push ds				; preserve (ds)
;; push bx				; preserve (bx) 		       ;AN000;
   cmp	es:[di].sf_mft,ZERO
;  $if	nz,and				; if file is SHARED and 	       ;AC000;
   JZ $$IF11
   push di
   call clp				; do common setup code

   ASSUME DS:NOTHING

   pop	bp
;  $if	nc,and				; if no (lock conflict) error and      ;AC000;
   JC $$IF11

;	Its ok to set this lock.  Get a free block and fill it in
;	(es:bp) = sft
;	(ds:si) = pointer to name record
;	(ax:bx) = fba lock area
;	(cx:dx) = lba lock area
;	(ds:di) = pointer to pointer to previous lock
;	(TOS)	= saved (bx)
;	(TOS+1) = saved (ds)
;	(TOS+2) = saved (bp)

   call OFL				; (ds:di) = pointer to new, orphan lock record
;  $if	nc				; if space available		       ;AC000;

;SR;
; We have to return out_of_buffer error code in case no more locks can be
;allocated. The old code was returning a lock violation for this case also.
;
       JC out_of_space

       mov  WORD PTR [di].rlr_sptr,bp	; store SFT offset
       mov  WORD PTR [di].rlr_sptr+2,es ; store SFT offset
       mov  [di].rlr_fba+2,ax
       mov  [di].rlr_fba,bx		; store lock range
       mov  [di].rlr_lba+2,cx
       mov  [di].rlr_lba,dx

;	add to front of chain
;
;	(ds:si) = fwa MFT name record

       mov  ax,[si].mft_lptr
       mov  [di].rlr_next,ax
       mov  [si].mft_lptr,di
;
; Set process ID of lock
;
       mov  ax,proc_id
       mov  [di].rlr_pid,ax

;
;;     pop  bx				; recover lock type		       ;AN000;
;;     push bx				; restore the stack		       ;AN000;
;;     mov  [di].rlr_type,bx		; set the rlr_type field	       ;AN000;
       clc				; we finished OK

;  $else				;				       ;AC000;
   JMP SHORT $$EN11

;SR;
;We have to return a separate error code if we run out of space for locks
;
out_of_space:
       mov	ax,error_sharing_buffer_exceeded
       jmp	short $$EN11

$$IF11:

       mov  ax,error_lock_violation
       stc

;  $endif				;				       ;AC000;
$$EN11:

;; pop	bx				;				       ;AN000;
   pop	ds
   pop	bp				;				       ;AC000;

   ret					; return - all set

   EndProc Set_Block

   BREAK <Clr_Block - Try to clear a lock>

;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:	   Clr_Block - clear byte range lock on a file
;
;  FUNCTION:	   Clr_Block clears a lock on a specified range of a file.
;		   Locks are set via set_block.
;
;  INPUT:	   (ES:DI) = SFT address
;		   (CX:DX) = offset of area
;		   (SI:AX) = length of area
;		   (BX)    = 0 lock all operations
;			   = 1 lock write operations
;		   User_ID = 16-bit user id of issuer
;		   Proc_ID = 16-bit process id of issuer
;		   (SS) = DOSData
;
;  OUTPUT:	   Lock record removed for block specified.
;
;  REGISTERS USED: ALL but DS
;  (NOT RESTORED)
;
;  LINKAGE:	   Invoked by:	Clr_Mult_Block
;
;  EXTERNAL	   Invoke: CLP (SLE), OFL
;  REFERENCES:
;
;  NORMAL	   'C' clear if no error
;  EXIT:
;
;  ERROR	   'C' set if error
;  EXIT:	     (ax) = error code
;			       ('error_lock_violation' if conflicting locks or
;			       range does not exactly match previous lock)
;
;  CHANGE	04/15/87 - lock only write support
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************+ START OF PSEUDOCODE +**************************************
;
;	START Clr_Block
;
;	if file is SHARED and
;	if lock is valid and
;	if SFT matches and
;	if PROC_ID matches
;		if lock_reqest = lock_type
;			unchain the lock
;			put defunct lock on free chain
;			clear error status
;		else
;			set error status
;		endif
;	else
;		flush the stack
;		set error status
;	endif
;	if error
;		load return code
;	endif
;	return
;
;	END Clr_Block
;
;******************+  END  OF PSEUDOCODE +**************************************

   Procedure Clr_Block,NEAR

   ASSUME ES:NOTHING,DS:NOTHING

   Context DS
   push ds
;; push bx				; save type of operation	       ;AN000;
   cmp	es:[di].sf_mft,ZERO

;  $if	nz,and				; if file is SHARED and 	       ;AC000;
   JZ $$IF14

   push di
   call clp				; do common setup code

   ASSUME DS:NOTHING

   pop	bp				; ES:BP points to sft.
;; pop	bx				; recover the type of operation        ;AN000;

;  $if	c,and				; if lock exists and		       ;AC000;
   JNC $$IF14
;  $if	z,and				; if range given correctly and	       ;AC000;
   JNZ $$IF14
;
;	We've got the lock
;
;	(ds:di) = address of pointer (offset) to previous lock record
;	(es:BP) = sft address
;
; Now comes the tricky part.  Is the lock for us?  Does the lock match the SFT
; that was given us?  If not, then error.
;
   mov	si,[di] 			; (DS:SI) = address of lock record
   cmp	word ptr [si].rlr_sptr,bp

;  $if	z,and				; if SFT matches and		       ;AC000;
   JNZ $$IF14

   mov	bp,es
   cmp	word ptr [si].rlr_sptr+2,bp
;  $if	z,and				; (check both words of SFT pointer)    ;AC000;
   JNZ $$IF14
   mov	bp,proc_id
   cmp	[si].rlr_pid,bp

;; $if	z,and				; if PROC_ID matches		       ;AC000;
;  $if	z				; if PROC_ID matches		       ;AC006;
   JNZ $$IF14
;
; Make sure that the type of request and the lock type match
;
;; cmp	bx,lock_all			;				       ;AN000;

;; $IF	E,OR				; if unlocking all or		       ;AN000;

;; mov	bp,[si].rlr_type		; get lock type 		       ;AN000;
;; cmp	bp,rlr_lall			; is it lock all?		       ;AN000;

;; $IF	NE				; if not a LOCK ALL lock	       ;AN000;
;
; The locks match the proper open invocation.  Unchain the lock
;
       mov  ax,[si].rlr_next
       mov  [di],ax			; chain it out

;	put defunct lock record on the free chain
;
;	(ds:si) = address of freed lock rec

       mov  ax,Frelock
       mov  [si].rlr_next,ax
       mov  Frelock,si
       clc

;  $else				; we have an error		       ;AC000;
   JMP SHORT $$EN14
$$IF14:

       stc

;  $endif				; Endif - an error		       ;AC000;
$$EN14:

;  $if	c				; If an error was found 	       ;AC000;
   JNC $$IF17

       mov  ax,error_lock_violation

;  $endif				; Endif - an error was found	       ;AC000;
$$IF17:

   pop	ds				; restore DS

   ret


   EndProc Clr_Block

   BREAK <CLP - Common Lock Preamble>

;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:	   CLP - Common Lock Preamble
;
;  FUNCTION:	   This routine contains a common code fragment for set_block
;		   and clr_block.
;
;  INPUT:	   (ES:DI) = SFT address
;		   (CX:DX) = offset of area
;		   (SI:AX) = length of area
;		   User_ID = 16-bit user id of issuer
;		   Proc_ID = 16-bit process id of issuer
;		   (SS) = (DS) = DOSData
;

⌨️ 快捷键说明

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