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

📄 gshare.asm

📁 DOS 源代码 系列之 command 源码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
   sub	al,al				; don't create an entry
   call FNM				; find the name gain
   jnc	mclo1				; got still more
   clc

;	exit.  'C' and (ax) setup
;
;	(TOS+2:TOS) = address of ASCIZ string

mclo9: pop si				; clean stack
   pop	ds
   LeaveCrit critShare

   ret

   EndProc MFTcloN

   BREAK <Set_Mult_Block - Try to set multiple locks>

;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:	   Set_Mult_Block  -  Set Multiple Block Locks
;
;  FUNCTION:	   Set_Mult_Block sets a lock on 1 or more specified ranges
;		   of a file.  An error is returned if any lock range conflicts
;		   with another. Ranges of Locks are cleared via Clr_Mult_Block.
;
;		   In DOS 3.3 only one lock range could be set at a time using
;		   Set_Block.  For DOS 4.00 this routine will replace Set_Block
;		   in the jump table and will make repeated calls to Set_Block
;		   in order to process 1 or more lock ranges.
;
;		   NOTE: - This is an all new interface to IBMDOS
;
;  INPUT:	   (AL) = 0  - lock all
;			= 80 - lock write
;		   (CX) = the number of lock ranges
;		   (DS:DX) = pointer to the range list
;		   (ES:DI) = SFT address
;		   User_ID = 16-bit user id of issuer
;		   Proc_ID = 16-bit process id of issuer
;		   (SS) = DOSData
;
;  OUTPUT:	   Lock records filled in for all blocks specified
;
;  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 Set_Mult_Block
;
;	count = start_count
;	search till count = 0
;		invoke Load_Regs
;		invoke Set_Block
;	exit if error
;		clear_count = start_count - current_count
;		loop till clear_count = 0
;			invoke Load_Regs
;			invoke Clr_Block
;		leave if error
;		end loop
;		set error status
;	orelse
;	endloop
;		set successful status
;	endsrch
;	if error status
;		load return code
;	endif
;	return
;
;	END Set_Mult_Block
;
;******************+  END  OF PSEUDOCODE +**************************************

   Procedure Set_Mult_Block,NEAR

;	PUSH	DS			;ICE
;	push	bx			;ICE
;	push	ax			;ICE

;	mov	bx,0140H		;ICE
;	xor	ax,ax			;ICE
;	mov	ds,ax			;ICE
;	mov	ax,word ptr ds:[bx]	;ICE
;	mov	word ptr ds:[bx],ax	;ICE

;	pop	ax			;ICE
;	pop	bx			;ICE
;	POP	DS			;ICE



   EnterCrit critShare			;				       ;AN000;

   ASSUME ES:NOTHING,DS:NOTHING 	;				       ;AN000;
;	      set up for loop

;      WE HAVE:   (from IBMDOS) 	|	  WE NEED:   (for Set_Block)

; (AL)	  = 0 - lock all		|    (BX)    = 0 lock all operations
;	  = 80- 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

;  int 3
   nop
   nop

   mov	DS_Org,ds			;an000;save entry DS

   Context DS				;				       ;AN000;
   CMP	CX,01h				;DO WE HAVE A COUNT?		       ;AN000;

;; $if	ae				; if the count was valid	       ;AN000;
;  $if	e				; if the count was valid	       ;AC006;
   JNE $$IF1

;;     PUSH CX				; count = start_count		       ;AN000;
;;     PUSH DX				; save pointer to range list	       ;AN000;
       MOV  BP,DX			; save current index into list	       ;AN000;
;;     AND  AX,0080H			; clear high byte and be sure low is   ;AN000;
					; set if applicable
;;     ROL  AL,1			; move high bit to bit 0
;;     MOV  BX,AX			; SET UP TYPE OF LOCK		       ;AN000;

;;     $do				; loop till count = 0		       ;AN000;
;;	   cmp	cx,00			;an000;see if at end
;;     $leave e 			;an000;exit if at end
;;	   push cx			;an000;save cx - our counter
;;	   push di			;an000;save di - our SFT pointer
       call load_regs			;an000;load the registers for call
					;      to set_block
       call set_block			;an000;set the lock block
;SR;
; This routine destroys the error code returned by set_block and returns
;lock violation in case of any error. We want to preserve the error code
;returned by set_block. So, we are going to jump directly to return point
;on an error.
;
       jc   $$IF4

;;	   pop	di			;an000;restore our SFT pointer
;;	   pop	cx			;an000;restore cx - our counter
;;     $leave c 			;an000;on error exit loop
;;	   dec	cx			;an000;decrease counter
;;     $enddo				;an000;end loop

;;     $if  c				;an000;if an error occurred
;;	   pop	dx			;an000;restore range list pointer
;;	   pop	ax			;an000;obtain original count
;;	   sub	ax,cx			;an000;determine how many locks set
;;	   mov	cx,ax			;an000;set the loop counter with count
;;	   mov	bp,dx			;an000;set bp to point to range list
;;	   $do				;an000;while cx not = 0
;;	       cmp  cx,00		;an000;at end?
;;	   $leave e			;an000;yes, exit
;;	       push cx			;an000;save cx - our counter
;;	       push di			;an000;save di - our SFT pointer
;;	       call load_regs		;an000;load the registers for call
					;      to clr_block
;;	       call clr_block		;an000;clear the locks
;;	       pop  di			;an000;restore our SFT pointer
;;	       pop  cx			;an000;restore cx - our counter
;;	   $leave c			;an000;on error exit
;;	       dec  cx			;an000;decrease counter
;;	   $enddo			;an000;
;;	   stc				;an000;signal an error occurred
;;     $else				;an000;no error occurred in locking
;;	   pop	ax			;an000;clear off the stack
;;	   pop	ax			;an000;   to balance it
;;	   clc				;an000;signal no error occurred
;;     $endif				;an000;
;  $else				;an000;cx was 0 - this is an error
   JMP SHORT $$EN1
$$IF1:
       stc				;an000;signal an error occurred
;  $endif				;				       ;an000;
$$EN1:

;  $if	c				; if there was an error 	       ;AN000;
   JNC $$IF4
       MOV  AX,error_lock_violation	; load the return code		       ;AN000;
;  $endif				; endif there was an error	       ;AN000;
$$IF4:

   LeaveCrit critShare			;				       ;AN000;

   ret					; return - all set		       ;AN000;

   EndProc Set_Mult_Block

   BREAK <Load_Regs - Load Registers for ?_Block call>

;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:	   Load_Regs - Load Registers for ?_Block calls
;
;  FUNCTION:	   This subroutine loads the High and Low Offsets and the
;		   High and Low lengths for Lock ranges from the Range List.
;
;  INPUT:	   (DS_Org:PB) - Range list entry to be loaded
;
;  OUTPUT:	   (DX) - Low Offset
;		   (CX) - High Offset
;		   (AX) - Low Length
;		   (SI) - High Length
;
;  REGISTERS USED: AX CX DX BP SI
;  (NOT RESTORED)
;
;  LINKAGE:	   Called by: Set_Mult_Block, Clr_Mult_Block
;
;  EXTERNAL	   none
;  REFERENCES:
;
;  NORMAL	   none
;  EXIT:
;
;  ERROR	   none
;  EXIT:
;
;  CHANGE	   04/15/87 - first release
;  LOG:
;
;******************* END OF SPECIFICATIONS *************************************
;******************+ START OF PSEUDOCODE +**************************************
;
;	  START Load_Regs
;
;	  recover index into range list
;	  advance pointer to next entry
;	  load DX - Low Offset
;	  load CX - High Offset
;	  load AX - Low Length
;	  load SI - High Length
;	  return
;
;	  END Load_Regs
;
;******************+  END  OF PSEUDOCODE +**************************************

   Procedure Load_Regs,NEAR

   push ds				; save our DS			       ;an000;
   mov	ds,DS_Org			; get range list segment	       ;an000;
   mov	si,bp				; recover pointer		       ;AN000;
   ADD	BP,08h				; move to next entry in list	       ;AN000;
   MOV	DX,[SI] 			; low position			       ;AN000;
   MOV	CX,[SI+2]			; high position 		       ;AN000;
   MOV	AX,[SI+4]			; low length			       ;AN000;
   MOV	SI,[SI+6]			; high length			       ;AN000;
   pop	ds				; restore DS			       ;an000;

   ret					;				       ;AN000;

   EndProc Load_Regs

   BREAK <Clr_Mult_Block - Try to clear multiple locks>

;******************* START OF SPECIFICATIONS ***********************************
;
;  NAME:	   Clr_Mult_Block  -  Clear Multiple Block Locks
;
;  FUNCTION:	   Clr_Mult_Block removes the locks on 1 or more specified
;		   ranges of a file.  An error is returned if any lock range
;		   does not exactly match. Ranges of Locks are set via
;		   Set_Mult_Block.
;
;		   In DOS 3.3 only one lock range could be cleared at a time
;		   using Clr_Block.  For DOS 4.00 this routine will replace
;		   Clr_Block in the jump table and will make repeated calls
;		   to Set_Block in order to process 1 or more lock ranges.
;
;		   NOTE: - This is an all new interface to IBMDOS
;			 - an unlock all 'lock all' request will unlock both
;			   'lock all' and 'lock write'.
;			 - an unlock all 'lock write' request will not unlock
;			   'lock all's. It will only unlock 'lock write's.
;			  (if you can understand the above statement,
;			  understanding the code will be easy!)
;
;  INPUT:	   (AL) = 0 - lock all
;			= 80- lock write
;		   (CX) = the number of lock ranges - NB: all if -1 ***
;		   (DS:DX) = pointer to the range list
;		   (ES:DI) = SFT address
;		   User_ID = 16-bit user id of issuer
;		   Proc_ID = 16-bit process id of issuer
;		   (SS) = DOSData
;
;  OUTPUT:	   Lock records filled in for all blocks specified
;
;  REGISTERS USED: ALL but DS
;  (NOT RESTORED)
;
;  LINKAGE:	   IBMDOS Jump Table
;
;  EXTERNAL	   Invoke: Load_Regs, Set_Block, Clr_Block, Clr_List
;  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_Mult_Block
;
;	if count is valid and
;	if file (SFT) is 'shared' then
;		if count = all
;			find first RLR
;			loop till all RLR cleared
;				if PROC_ID matches and
;				if UID matches and
;				if SFT matches then
;					if ulocking lock_all or
;					if this RLR is lock_write
;						clear the lock
;					endif
;				endif
;				find next RLR
;			end loop
;		else
;			invoke Clr_List
;		endif
;		set successful status
;	else
;		set error status
;	endif
;	if error
;		load return code
;	endif
;
;	ret
;
;	END Clr_Mult_Block
;
;******************+  END  OF PSEUDOCODE +**************************************

   Procedure clr_mult_block,NEAR


lock_all equ 0h

;	PUSH	DS			;ICE
;	push	bx			;ICE
;	push	ax			;ICE

;	mov	bx,0140H		;ICE
;	xor	ax,ax			;ICE
;	mov	ds,ax			;ICE
;	mov	ax,word ptr ds:[bx]	;ICE
;	mov	word ptr ds:[bx],ax	;ICE

;	pop	ax			;ICE
;	pop	bx			;ICE
;	POP	DS			;ICE

   EnterCrit critShare			;				       ;AN000;

   ASSUME ES:NOTHING,DS:NOTHING 	;				       ;AN000;

;  int 3
   nop
   nop

   mov	DS_Org,DS			;an000;save entry DS

   Context DS				;				       ;AN000;

   CMP	CX,01h				; do we have a count?		       ;AN000;
;; $IF	AE,AND				; IF A VALID COUNT
;  $IF	E,AND				; IF A VALID COUNT		       ;AC006;
   JNE $$IF6
   cmp	es:[di].sf_mft,0		; is this SFT shared?		       ;AN000;
;  $IF	NE				; AND IF FILE IS 'SHARED' THEN
   JE $$IF6

;      WE HAVE:   (from IBMDOS) 	|	  WE NEED:

; (AL)	  = 0 - lock all		|    (AX)    = 0 lock all operations
;	  = 80- lock write		|	     = 1 lock write operations
; (CX)	  = - 1  (unlock all locks)	|    (DS)    = CS
;					|    (DS:DI) = previous RLR
;					|    (DS:SI) = current RLR
; (ES:DI) = current SFT 		|

;;     and  ax,0080h			;be sure it is set right (mask 80 bit) ;AC002;
					;    existing interface
;;     rol  al,1			;put high bit in bit 0		       ;AC002;

;;     CMP  CX,-1h			;				       ;AN000;
;;     $IF  E				; IF unlock all locks then	       ;AN000;

;;	   push cs			;				       ;AN000;
;;	   pop	ds			;				       ;AN000;
;;	   mov	cx,di			; ES:CX is the SFT		       ;AN004;

;	   ASSUME ds:nothing

;;	   mov	si,es:[di].sf_mft	; DS:SI points to MFT		       ;AN000;

;;	   lea	di,[si].mft_lptr	; DS:DI = addr of ptr to lock record   ;AN000;
;;	   mov	si,[di] 		; DS:SI = address of 1st lock record   ;AN000;

;;	   $DO				; loop through the RLR's               ;AN000;

;	DS:DI = points to previous RLR or MFT if no RLR.
;	DS:SI = points to current RLR
;	ES:CX = SFT address
;	AX    = lock type

;;	       and  si,si		; are we at the end of the chain?      ;AN000;
;;	   $LEAVE Z			; we'er done with CF = 0               ;AN000;

;;	       mov  bp,[si].rlr_pid	; get PROC_ID			       ;AN000;
;;	       cmp  bp,PROC_ID		; is it ours?			       ;AN000;
;;	       $IF  E,AND		;				       ;AN000;
;;	       mov  bp,es		;				       ;AN000;
;;	       cmp  bp,WORD PTR [si].rlr_sptr+2 ;			       ;AC004;
;;	       $IF  E,AND		;				       ;AN000;
;;	       cmp  cx,WORD PTR [si].rlr_sptr ; 			       ;AC004;
;;	       mov  si,[di]		; restore pointer to current (using    ;AN000;
					;			     previous)
;;	       $IF  E			; if it is ours 		       ;AN000;

;	this is it. its OURS !

;;		   cmp	ax,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;

;	remove the RLR from the chain

;;		       mov  bx,[si].rlr_next ; get the pointer to the next RLR ;AN000;
;;		       mov  [di],bx	; install it in the last	       ;AN000;

;	put defunct lock record on the free chain

;;		       mov  bx,Frelock	;				       ;AN000;
;;		       mov  [si].rlr_next,bx ;				       ;AN000;
;;		       mov  Frelock,si	;				       ;AN000;
;;		       mov  si,di	; back up to last		       ;AN000;

;;		   $ENDIF		; should we unlock it		       ;AN000;

;;	       $ENDIF			; it was ours!			       ;AN000;

;	advance to next RLR

;;	       mov  di,si		; load address of next RLR	       ;AN000;
;;	       mov  si,[di]		; update pointer to next RLR	       ;AN000;

;;	   $ENDDO			; loop back to the start	       ;AN000;

;;     $ELSE				; else, its a LIST !		       ;AN000;

;	      set up for loop

⌨️ 快捷键说明

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