	PAGE	,132			; 						 ;AN000;
;	SCCSID = @(#)ifsinit.asm	1.0 87/05/11					 ;AN000;
TITLE	IFSFUNC INITIALIZATION ROUTINES - Routines for ifs				 ;AN000;
NAME	IFSINIT 									 ;AN000;
;***********************************************************************************	 ;AN000;
;											 ;AN000;
; IFS Initialization Routines								 ;AN000;
;											 ;AN000;
; IFSINIT										 ;AN000;
;											 ;AN000;
; REVISION HISTORY:									 ;AN000;
;	A000 - Original version 4.00	MAY 1987					 ;AN000;
;	A001 - PTM 331	Entry point for device ioctl
;	A002 - PTM 430	Renumber parse errors
;	A003 - DCR  96	Transfer IFS DOS callbacks to IFSFUNC
;	A004 - PTM 696	IFSFUNC hang w/no drivers
;	A005 - PTM 541	Parse problem
;	A006 - PTM 1227 DOS Version Check problem
;	A007 - PTM  842 Error messages in ifsfunc
;	A008 - PTM 1950 Autoattach when 2 ifs drivers loaded & 1st fails attach
;	A009 - PTM 2249 Autoattach must set isifs bit in cds
;	A010 - PTM 2827 Error proc problems	1/88   RMG
;	A011 - PTM 3334 put back reset environment call  2/88 rmg
;	A012 - PTM 4140 dos ext error msg enhancement - semaphore processing	4/19/88 RMG
;	A013 - DCR 526	New INT 2FH Share interface not to trigger logic install 4/19/88 RMG
;
; LOC -
;
;***********************************************************************************
											 ;AN000;
.xlist											 ;AN000;
.xcref											 ;AN000;
INCLUDE IFSFSYM.INC									 ;AN000;
INCLUDE IFSSYM.INC									 ;AN000;
INCLUDE DOSSYM.INC									 ;AN000;
INCLUDE DEVSYM.INC									 ;AN000;
include sysmsg.inc								 ;AN000;
msg_utilname <IFSFUNC>			; resident msgret stuff 		 ;AN000;
.cref											 ;AN000;
.list											 ;AN000;
.sall											 ;AN000;
											 ;AN000;
AsmVars <IBM, INSTALLED, DEBUG, PATHGEN>						 ;AN000;
											 ;AN000;
IFSSEG	SEGMENT WORD PUBLIC 'IFSSEG'                                                     ;AN000;
IFSSEG	ENDS										 ;AN000;
											 ;AN000;
include dosseg.asm									 ;AN000;
											 ;AN000;
DATA		SEGMENT WORD PUBLIC 'DATA'                                               ;AN000;
	; DOSGROUP data 								 ;AN000;
	extrn	DataVersion:WORD	; version number of DOS data.			 ;AN000;
	extrn	SFTFCB:DWORD		; FCB SFT cache 				 ;AN000;
	extrn	KeepCount:WORD		; FCB SFT cache 				 ;AN000;
	Extrn	CDSAddr:DWORD								 ;AN000;
	Extrn	CDSCount:BYTE								 ;AN000;
	Extrn	DummyCDS:BYTE								 ;AN000;
	Extrn	CritPatch:WORD								 ;AN000;
DATA		ENDS									 ;AN000;
											 ;AN000;
IFSSEG	SEGMENT WORD PUBLIC 'IFSSEG'                                                     ;AN000;
	ASSUME	SS:DOSGROUP,CS:IFSSEG							 ;AN000;
											 ;AN000;
	;IFS Data									 ;AN000;
											 ;AN000;
	Extrn	CDSAlt:DWORD								 ;AN000;
	Extrn	DFLAddr:DWORD								 ;AN000;
	Extrn	DFLCount:BYTE								 ;AN000;
;;;aliasExtrn	NLAddr:DWORD								 ;AN000;
;;;aliasExtrn	NLSIZE:WORD								 ;AN000;
	Extrn	INT_2F_5:BYTE								 ;AN000;
	Extrn	NEXT_2F_5:DWORD 							 ;AN000;
	Extrn	IFSR:WORD								 ;AN000;
	Extrn	CD1:WORD								 ;AN000;
	Extrn	DF1:WORD								 ;AN000;
	Extrn	SFF1:WORD								 ;AN000;
	Extrn	THISIFS:DWORD								 ;AN000;
	Extrn	IFSPROC_FLAGS:WORD							 ;AN000;
	Extrn	IFSFUNC_FLAGS:WORD							 ;AN000;
	Extrn	UNC_FS_HDR:DWORD							 ;AN000;
	Extrn	DEVICE_CB@_OFFSET:WORD							 ;AN000;
	Extrn	IFS_ATTRS:WORD
	Extrn	RODS_LABEL:BYTE 							 ;AN000;
	Extrn	IFSSEM:BYTE
											 ;AN000;
	PUBLIC	CODESIZE								 ;AN000;
CODESIZE	DB	'RMG'                                                            ;AN000;
		DB	30H								 ;AN000;
		DB	30H								 ;AN000;
		DB	30H								 ;AN000;
		DB	30H								 ;AN000;
		DB	30H								 ;AN000;
		DB	20H								 ;AN000;
	PUBLIC	TOTSIZE 								 ;AN000;
TOTSIZE 	DB	30H								 ;AN000;
		DB	30H								 ;AN000;
		DB	30H								 ;AN000;
		DB	30H								 ;AN000;
		DB	30H								 ;AN000;
		DB	20H								 ;AN000;
											 ;AN000;
											 ;AN000;
											 ;AN000;
Break	<INT 2F handler>								 ;AN000;
											 ;AN000;
IF	DEBUG										 ;AN000;
Procedure   NetPointers,NEAR								 ;AN000;
	ASSUME	CS:IFSSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING				 ;AN000;
	LDS	SI,[DFLAddr]								 ;AN000;
;;;aliasLES	DI,[NLAddr]								 ;AN000;
	return										 ;AN000;
EndProc NetPointers									 ;AN000;
											 ;AN000;
Procedure   NetPointers2,NEAR								 ;AN000;
	ASSUME	CS:IFSSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING				 ;AN000;
	PUSH	CS									 ;AN000;
	POP	DS									 ;AN000;
ASSUME	DS:IFSSEG									 ;AN000;
	MOV	CX,[DFLCount]								 ;AN000;
;;;aliasMOV	DX,[NLSIZE]								 ;AN000;
	return										 ;AN000;
EndProc NetPointers2									 ;AN000;
ENDIF											 ;AN000;
											 ;AN000;
IF	PATHGEN 									 ;AN000;
Procedure   GetIFSFCSinES,NEAR								 ;AN000;
	ASSUME	CS:IFSSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING				 ;AN000;
	PUSH	CS									 ;AN000;
	POP	ES									 ;AN000;
	return										 ;AN000;
EndProc     GetIFSFCSinES								 ;AN000;
ENDIF											 ;AN000;
											 ;AN000;
Procedure   UnusedFunc,NEAR								 ;AN000;
	ASSUME	CS:IFSSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING				 ;AN000;
	fmt <>,<>,<"Unused IFSFUNC function issued\n">                                   ;AN000;
	MOV	AX,error_invalid_function						 ;AN000;
	STC										 ;AN000;
	return										 ;AN000;
EndProc UnusedFunc									 ;AN000;
											 ;AN000;
; the following multiplex functions are implemented:					 ;AN000;
											 ;AN000;
retn1	DD  ?										 ;AN000;
DMY	DW  ?										 ;AN000;
CONT	DD  ?										 ;AN000;
FOO	DW  Leave2F									 ;AN000;
											 ;AN000;
INT2F	PROC	FAR									 ;AN000;
	ASSUME	CS:IFSSEG,DS:NOTHING,ES:NOTHING,SS:DOSGroup				 ;AN000;
	CMP	AH,multIFS								 ;AN000;
	JZ	IDispatch								 ;AN000;
	JMP	CONT									 ;AN000;
Leave2F:										 ;AN000;
	RET										 ;AN000;
INT2F	ENDP										 ;AN000;
											 ;AN000;
Procedure   IDispatch,NEAR								 ;AN000;
	POP	WORD PTR retn1		; remove long return				 ;AN000;
	POP	WORD PTR retn1+2 							 ;AN000;
	POP	DMY			; remove flags					 ;AN000;
	XCHG	AX,BX			; save bx/move index to index reg		 ;AN000;
	SHL	BL,1			; convert byte to word index			 ;AN000;
	XOR	BH,BH			; convert to word index 			 ;AN000;
	POP	DMY			; save fictitious AX				 ;AN000;
	PUSH	DMY			; restore spot on stack 			 ;AN000;
	PUSH	WORD PTR retn1+2 	; restore long return				 ;AN000;
	PUSH	WORD PTR retn1								 ;AN000;
	PUSH	FOO			; place near address of far return		 ;AN000;
	PUSH	CS:IFStable[BX] 	; place destination routine			 ;AN000;
	XCHG	AX,BX			; restore BX					 ;AN000;
	MOV	AX,DMY			; restore AX					 ;AN000;
	STI				; let Mani see Clock ticks			 ;AN000;
ShortReturn:										 ;AN000;
	return				; go to routine (dispatch for Aaron)		 ;AN000;
											 ;AN000;
EDW	MACRO	name									 ;AN000;
	extrn	name:near								 ;AN000;
	DW	name									 ;AN000;
ENDM											 ;AN000;
											 ;AN000;
IFSTable    LABEL   WORD								 ;AN000;
	DW	IFSInstall								 ;AN000;
	EDW	IFS_RMDIR		    ;	1   IFS_RMDIR				 ;AN000;
	EDW	IFS_SEQ_RMDIR		    ;	2   IFS_SEQ_RMDIR			 ;AN000;
	EDW	IFS_MKDIR		    ;	3   IFS_MKDIR				 ;AN000;
	EDW	IFS_SEQ_MKDIR		    ;	4   IFS_SEQ_MKDIR			 ;AN000;
	EDW	IFS_CHDIR		    ;	5   IFS_CHDIR				 ;AN000;
	EDW	IFS_CLOSE		    ;	6   IFS_CLOSE				 ;AN000;
	EDW	IFS_COMMIT		    ;	7   IFS_COMMIT				 ;AN000;
	EDW	IFS_READ		    ;	8   IFS_READ				 ;AN000;
	EDW	IFS_WRITE		    ;	9   IFS_WRITE				 ;AN000;
	EDW	IFS_XLOCK		    ;	10  IFS_XLOCK				 ;AN000;
	DW	UnusedFunc		    ;	11					 ;AN000;
	EDW	IFS_DISK_INFO		    ;	12  IFS_DISK_INFO			 ;AN000;
	EDW	IFS_SET_FILE_ATTRIBUTE	    ;	13  IFS_SET_FILE_ATTRIBUTE		 ;AN000;
	EDW	IFS_SEQ_SET_FILE_ATTRIBUTE  ;	14  IFS_SEQ_SET_FILE_ATTRIBUTE		 ;AN000;
	EDW	IFS_GET_FILE_INFO	    ;	15  IFS_GET_FILE_INFO			 ;AN000;
	EDW	IFS_SEQ_GET_FILE_INFO	    ;	16  IFS_SEQ_GET_FILE_INFO		 ;AN000;
	EDW	IFS_RENAME		    ;	17  IFS_RENAME				 ;AN000;
	EDW	IFS_SEQ_RENAME		    ;	18  IFS_SEQ_RENAME			 ;AN000;
	EDW	IFS_DELETE		    ;	19  IFS_DELETE				 ;AN000;
	EDW	IFS_SEQ_DELETE		    ;	20  IFS_SEQ_DELETE			 ;AN000;
	EDW	IFS_OPEN		    ;	21  IFS_OPEN				 ;AN000;
	EDW	IFS_SEQ_OPEN		    ;	22  IFS_SEQ_OPEN			 ;AN000;
	EDW	IFS_CREATE		    ;	23  IFS_CREATE				 ;AN000;
	EDW	IFS_SEQ_CREATE		    ;	24  IFS_SEQ_CREATE			 ;AN000;
	EDW	IFS_SEQ_SEARCH_FIRST	    ;	25  IFS_SEQ_SEARCH_FIRST		 ;AN000;
	EDW	IFS_SEQ_SEARCH_NEXT	    ;	26  IFS_SEQ_SEARCH_NEXT 		 ;AN000;
	EDW	IFS_SEARCH_FIRST	    ;	27  IFS_SEARCH_FIRST			 ;AN000;
	EDW	IFS_SEARCH_NEXT 	    ;	28  IFS_SEARCH_NEXT			 ;AN000;
	EDW	IFS_ABORT		    ;	29  IFS_ABORT				 ;AN000;
	EDW	IFS_ASSOPER		    ;	30  IFS_ASSOPER 			 ;AN000;
	EDW	Printer_GETSET_STRING	    ;	31  Printer_GETSET_STRING		 ;AN000;
	EDW	IFSFlushBuf		    ;	32  IFS_Flush_Buf			 ;AN000;
	EDW	IFS_LSEEK		    ;	33  IFS_LSEEK				 ;AN000;
	EDW	IFS_RESET_ENVIRONMENT	    ;	34  IFS_RESET_ENVIRONMENT	       ;AN000;
	EDW	IFS_DEVICE_CHECK	    ;	35  IFSDeviceCheck			 ;AN000;
	EDW	IFS_DEVICE_CLOSE	    ;	36  IFSDeviceClose			 ;AN000;
	EDW	IFS_DEVICE_OPER 	    ;	37  IFSDeviceOper			 ;AN000;
	EDW	IFS_SPOOL_ECHO_CHECK	    ;	38  IFSSpoolEchoCheck			 ;AN000;
	DW	UnusedFunc		    ;	39					 ;AN000;
	DW	UnusedFunc		    ;	40					 ;AN000;
	DW	UnusedFunc		    ;	41					 ;AN000;
	EDW	SERVER_DOSCALL_CLOSEFILES_FOR_UID ; 42			    util	 ;AN000;
	EDW	DEVICE_IOCTL		    ;	43			    dev 	 ;AN001;
	EDW	IFS_UPDATE_CB		    ;	44  UPDATECB		    util	 ;AN000;
	EDW	IFS_FILE_XATTRIBUTES	    ;	45			    hand	 ;AN000;
	EDW	IFS_XOPEN		    ;	46  XOPEN		    file	 ;AN000;
	EDW	IFS_DEPENDENT_IOCTL	    ;	47			    util	 ;AN000;
											 ;AN000;
	IF	DEBUG									 ;AN000;
	DW	NetPointers		    ;	47  NetPointers 			 ;AN000;
	DW	NetPointers2		    ;	48  NetPointers2			 ;AN000;
	ENDIF										 ;AN000;
											 ;AN000;
	IF	PATHGEN 								 ;AN000;
	DW	GetIFSFCSinES		    ;	49 (if debug) GetRedirCSinES		 ;AN000;
					    ;	47 (if NOT debug) GetRedirCSinES	 ;AN000;
	ENDIF										 ;AN000;
											 ;AN000;
IFSInstall:										 ;AN000;
	MOV	AL,0FFh 								 ;AN000;
	MOV	BX,IFS_ATTRS
	return										 ;AN000;
EndProc IDispatch									 ;AN000;
											 ;AN000;
Procedure   EcritNet,NEAR								 ;AN000;
	ASSUME	SS:NOTHING								 ;AN000;
	PUSHF										 ;AN000;
	CLI										 ;AN000;
	PUSH	AX									 ;AN000;
	MOV	AX,8000h+CritNet							 ;AN000;
	INT	int_ibm 								 ;AN000;
	POP	AX									 ;AN000;
IF DEBUG										 ;AN000;
	JNC	NoCarry 								 ;AN000;
	fmt <>,<>,<"$p: ECritNet overflowed semaphore\n">                                ;AN000;
NoCarry:										 ;AN000;
ENDIF											 ;AN000;
	STI										 ;AN000;
	POPF										 ;AN000;
	return										 ;AN000;
EndProc EcritNet									 ;AN000;
											 ;AN000;
;											 ;AN000;
; Leave critical section for network.  Note that the first instruction (PUSH		 ;AN000;
; AX) here is used as the patch byte to enable the DOS critical section 		 ;AN000;
; routines...										 ;AN000;
;											 ;AN000;
;   NOTE!!! On a 286, this instruction issues POPF!!!					 ;AN000;
;											 ;AN000;
Procedure   LcritNet,NEAR								 ;AN000;
	PUSH	AX									 ;AN000;
	PUSHF										 ;AN000;
	CLI										 ;AN000;
IF DEBUG										 ;AN000;
	JGE	NoWrap									 ;AN000;
	fmt <>,<>,<"$p: LCritNet decrementing semaphore through zero\n">                 ;AN000;
NoWrap: 										 ;AN000;
ENDIF											 ;AN000;
											 ;AN000;
	MOV	AX,8100h+critNet							 ;AN000;
	INT	int_ibm 								 ;AN000;
	STI										 ;AN000;
	POPF				; NOTE that this restores entry 		 ;AN000;
	POP	AX									 ;AN000;
	return										 ;AN000;
EndProc LcritNet									 ;AN000;
											 ;AN000;
											 ;AN000;
Procedure   EcritIFS,NEAR								 ;AN000;
	ASSUME	SS:NOTHING								 ;AN000;
	PUSHF										 ;AN000;
	CLI										 ;AN000;
	PUSH	AX									 ;AN000;
	MOV	AX,8000h+CritIFS							 ;AN000;
	INT	int_ibm 								 ;AN000;
	POP	AX									 ;AN000;
	STI										 ;AN000;
	POPF										 ;AN000;
	return										 ;AN000;
EndProc EcritIFS									 ;AN000;
											 ;AN000;
Procedure   LcritIFS,NEAR								 ;AN000;
	PUSH	AX									 ;AN000;
	PUSHF										 ;AN000;
	CLI										 ;AN000;
	MOV	AX,8100h+critIFS							 ;AN000;
	INT	int_ibm 								 ;AN000;
	STI										 ;AN000;
	POPF				; NOTE that this restores entry 		 ;AN000;
	POP	AX									 ;AN000;
	return										 ;AN000;
EndProc LcritIFS									 ;AN000;
											 ;AN000;
	ASSUME	CS:IFSSEG,DS:NOTHING,ES:NOTHING,SS:DOSGroup				 ;AN000;
											 ;AN000;
INTERR: 										 ;AN000;
INTERRL:jmp	INTERRL 		; hang here - we're sick                         ;AN000;
											 ;AN000;
											 ;AN000;
	PUBLIC	TEMPBUF 								 ;AN000;
TEMPBUF LABEL	BYTE									 ;AN000;
; THE SPACE FROM HERE TO NETEND CONSTITUTES THE TEMP AREA OF IFSFUNC.			 ;AN000;
; WARNING DANGER!!!!!!!!!								 ;AN000;
;	DO NOT reduce the size of this area without first checking			 ;AN000;
;	all users of it. It is OK to make it BIGGER without checking.			 ;AN000;
; Current size: ??									 ;AN000;
											 ;AN000;
Break	<General IFSFUNC INIT>								 ;AN000;
;************************************************************************************	 ;AN000;
;											 ;AN000;
; map:	Resident:									 ;AN000;
;	IF_40 - (contifsinit) 2nd half of ifsfinit procedure  =  tempbuf area		 ;AN000;
;		allocate: DFL_LIST, altcds, sftfcb,					 ;AN000;
;		set TOTALSIZE								 ;AN000;
;	IFSFUNCINIT start								 ;AN000;
;	I_700 - INIT:	2nd half of IFSFUNCINIT 					 ;AN000;
;			INT 23,24 stuff 						 ;AN000;
;			call IFSFINIT							 ;AN000;
;			close std handles						 ;AN000;
;			enable critical section 					 ;AN000;
;			terms & stays							 ;AN000;
;	tempbuf ends									 ;AN000;
;	Transient:									 ;AN000;
;	IFSFINIT procedure								 ;AN000;
;	Set interrupt vectors - 2F							 ;AN000;
;	Call AUTO_ATTACH								 ;AN000;
;	allocate stuff (write over code)						 ;AN000;
;	jumps up to 2nd half								 ;AN000;
;	IFSFUNCINIT init code								 ;AN000;
;	version checks									 ;AN000;
;	error msg processing								 ;AN000;
;	free environment								 ;AN000;
;	parsing 									 ;AN000;
;	move stack									 ;AN000;
;	check size for everything							 ;AN000;
;	ifsfunc code size calculation							 ;AN000;
;	ifsfunc total size calculation							 ;AN000;
;	jmps to I_700									 ;AN000;
;	AutoAttach									 ;AN000;
;	CheckUNCpresence								 ;AN000;
;											 ;AN000;
;************************************************************************************	 ;AN000;
											 ;AN000;
; This Code must be protected from overwrite when the structures are			 ;AN000;
;  initialized										 ;AN000;
											 ;AN000;
											 ;AN000;
IF_40:						; CONTIFSINIT				 ;AN000;
ASSUME	DS:IFSSEG,ES:NOTHING,SS:NOTHING 						 ;AN000;
											 ;AN000;
;											 ;AN000;
; Allocate and init DFL_LIST								 ;AN000;
;											 ;AN000;
	MOV	WORD PTR DFLAddr,DI							 ;AN000;
	MOV	WORD PTR DFLAddr+2,ES							 ;AN000;
	MOV	AL,DFLCount								 ;AN000;
	XOR	AH,AH									 ;AN000;
	MOV	BX,SIZE DFLL_LIST							 ;AN000;
	MUL	BX									 ;AN000;
	MOV	CX,AX									 ;AN000;
	XOR	AX,AX									 ;AN000;
	REP	STOSB									 ;AN000;
											 ;AN000;
;;;aliasMOV	WORD PTR NLAddr,DI							 ;AN000;
;;;	MOV	WORD PTR NLAddr+2,ES							 ;AN000;
;;;	MOV	AX,NLSIZE								 ;AN000;
;;;	STOSW										 ;AN000;
;;;	XOR	AX,AX									 ;AN000;
;;;	STOSW										 ;AN000;
;;;aliasADD	DI,NLSIZE-4								 ;AN000;
;											 ;AN000;
; Allocate alt CDSs area								 ;AN000;
;											 ;AN000;
	TEST	IFSFUNC_FLAGS,UNC_INSTALLED						 ;AN000;
	JZ	IF_50									 ;AN000;
	MOV	WORD PTR CDSAlt,DI							 ;AN000;
	MOV	WORD PTR CDSAlt+2,ES							 ;AN000;
	PUSH	DS									 ;AN000;
	MOV	AX,(multDOS SHL 8) OR 3 						 ;AN000;
	INT	2FH									 ;AN000;
ASSUME	DS:DOSGROUP									 ;AN000;
	MOV	AL,CDSCount		;	Alt = Alloc ((sizeof(CDS)+1)*CDSCount);  ;AN000;
	XOR	AH,AH									 ;AN000;
	INC	AX									 ;AN000;
	MOV	BX,SIZE curdir_list							 ;AN000;
	MUL	BX									 ;AN000;
	ADD	DI,AX									 ;AN000;
	JMP	SHORT IF_55								 ;AN000;
IF_50:											 ;AN000;
	PUSH	DS									 ;AN000;
	MOV	AX,(multDOS SHL 8) OR 3 						 ;AN000;
	INT	2FH									 ;AN000;
ASSUME	DS:DOSGROUP									 ;AN000;
;											 ;AN000;
; Allocate new FCB cache if appropriate 						 ;AN000;
;											 ;AN000;
IF_55:											 ;AN000;
	CMP	BYTE PTR CS:NEWFCBCACHE,0  ; Damn forward reference			 ;AN000;
	JZ	IF_80			   ; JZ NO_FCB_CACHE				 ;AN000;
;											 ;AN000;
; We need to allocate (NewNumFCB * size of SF_entry) + size of sfTable. 		 ;AN000;
;											 ;AN000;
	CLI				; Diddling a DOS table, make sure		 ;AN000;
;											 ;AN000;
; Make dos point to new table								 ;AN000;
;											 ;AN000;
	MOV	WORD PTR SFTFCB,DI							 ;AN000;
	MOV	WORD PTR SFTFCB+2,ES							 ;AN000;
;											 ;AN000;
; Initialize table parts, next link and size						 ;AN000;
;											 ;AN000;
	MOV	WORD PTR ES:[DI.sfLink],-1						 ;AN000;
	MOV	WORD PTR ES:[DI.sfLink+2],-1						 ;AN000;
	MOV	CX,NewNumFCB								 ;AN000;
	MOV	ES:[DI.sfcount],CX							 ;AN000;
;											 ;AN000;
; Set up keepcount									 ;AN000;
;											 ;AN000;
	MOV	KeepCount,NewKeepVal							 ;AN000;
;											 ;AN000;
; Clean out the new FCB Cache								 ;AN000;
;											 ;AN000;
	LEA	DI,[DI].SFTable 		; Point to the FCB SFTs 		 ;AN000;
IF_60:						; CleanScan:				 ;AN000;
	MOV	ES:[DI.sf_ref_count],0							 ;AN000;
	MOV	WORD PTR ES:[DI.sf_position],0						 ;AN000;
	MOV	WORD PTR ES:[DI.sf_position+2],0					 ;AN000;
	ADD	DI,SIZE sf_entry							 ;AN000;
	LOOP	IF_60									 ;AN000;
	STI										 ;AN000;
IF_80:						; NO_FCB_CACHE: 			 ;AN000;
	POP	DS									 ;AN000;
ASSUME	DS:IFSSEG									 ;AN000;
											 ;AN000;
	MOV	[TOTALSIZE],DI		; Offset of 1st free byte			 ;AN000;
	POP	AX									 ;AN000;
	POP	BX									 ;AN000;
	POP	CX									 ;AN000;
	POP	DX									 ;AN000;
	POP	DI									 ;AN000;
	POP	SI									 ;AN000;
	POP	ES									 ;AN000;
	POP	DS									 ;AN000;
	return										 ;AN000;
											 ;AN000;
											 ;AN000;
											 ;AN000;
	ASSUME	CS:IFSSEG,DS:IFSSEG,ES:NOTHING,SS:STACK 				 ;AN000;
											 ;AN000;
.xlist											 ;AN000;
.xcref											 ;AN000;
	msg_services <MSGDATA>								 ;AN007;
	PUBLIC	SYSGETMSG
	msg_services <GETmsg>
.cref											 ;AN000;
.list											 ;AN000;
											 ;AN000;
Break	<Installable Network INIT>							 ;AN000;
											 ;AN000;
Totalsize   DW	    ?									 ;AN000;
											 ;AN000;
NEWFCBCACHE DB	    0									 ;AN000;
											 ;AN000;
INT_24: 				; INT 24 handler used during INIT.		 ;AN000;
	MOV	AL,3			;    FAIL any INT 24s				 ;AN000;
INT_23: 				; ^C handler used during INIT.			 ;AN000;
	IRET				;    ignores any ^C.				 ;AN000;
											 ;AN000;
I_700:					; Init						 ;AN000;
	ASSUME	CS:IFSSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING				 ;AN000;
;											 ;AN000;
; We are now going to set lots of INT vectors and other stuff. We need			 ;AN000;
; to make ourselves immune to INT 24 and ^C						 ;AN000;
;											 ;AN000;
	PUSH	CS									 ;AN000;
	POP	DS									 ;AN000;
	MOV	DX,OFFSET INT_23							 ;AN000;
	MOV	AX,(Set_Interrupt_Vector SHL 8) + 23H					 ;AN000;
	INT	21H									 ;AN000;
	MOV	DX,OFFSET INT_24							 ;AN000;
	MOV	AX,(Set_Interrupt_Vector SHL 8) + 24H					 ;AN000;
	INT	21H									 ;AN000;
	invoke	IFSFINIT			; Do general INIT			 ;AN000;
											 ;AN000;
	XOR	BX,BX									 ;AN000;
	MOV	CX,5				; StdIN,StdOUT,StdERR,StdAUX,StdPRN	 ;AN000;
I_720:						; Close STD handles before		 ;AN000;
						; keep process				 ;AN000;
	MOV	AH,CLOSE								 ;AN000;
	INT	21H									 ;AN000;
	INC	BX									 ;AN000;
	LOOP	I_720									 ;AN000;
											 ;AN000;
;											 ;AN000;
; Enable the critical section code.  This consists of replacing the RETs at		 ;AN000;
; the beginning of each critical section routine with a PUSH AX 			 ;AN000;
;											 ;AN000;
	PUSH	CS									 ;AN000;
	POP	DS				; ds - ifsseg				 ;AN000;
											 ;AN000;
	TEST	IFSFUNC_FLAGS,UNC_INSTALLED	; 1st check if unc fs loaded		 ;AN000;
	JZ	I_800				;   only do this for unc		 ;AN000;
	MOV	AH,Get_In_Vars			; do crit patch 			 ;AN000;
	INT	21h									 ;AN000;
	cld										 ;AN000;
	ASSUME	ES:DOSGroup								 ;AN000;
	MOV	AL,BYTE PTR LCritNet							 ;AN000;
	MOV	BX,OFFSET DOSGROUP:CritPatch						 ;AN000;
	CLI										 ;AN000;
I_760:						; Scan					 ;AN000;
	MOV	DI,ES:[BX]								 ;AN000;
	ADD	BX,2									 ;AN000;
	OR	DI,DI									 ;AN000;
	JZ	I_780									 ;AN000;
	stosb										 ;AN000;
	JMP	I_760									 ;AN000;
I_780:											 ;AN000;
	STI										 ;AN000;
I_800:											 ;AC012;moved
	MOV	CS:IFSSEM,0			; initialize ifs semaphores		 ;AN012;
;											 ;AN000;
; Compute total size for residency.							 ;AN000;
;											 ;AN000;
	MOV	DX,TotalSize			; size of code and structs		 ;AN000;
	ADD	DX,100H+0Fh			; Add size of header			 ;AN000;
	RCR	DX,1									 ;AN000;
	MOV	CL,3									 ;AN000;
	SHR	DX,CL									 ;AN000;
	MOV	AX,(Keep_Process SHL 8) + 0						 ;AN000;
	INT	21h									 ;AN000;
	MOV	AX,(EXIT SHL 8) + 1							 ;AN000;
	INT	21h									 ;AN000;
											 ;AN000;
											 ;AN000;
; %%%% CODE/DATA BELOW IS OVERLAYED WHEN STRUCTURES ARE SET UP				 ;AN000;
											 ;AN000;
NETEND	LABEL	BYTE									 ;AN000;
											 ;AN000;
	procedure IFSFINIT,NEAR 							 ;AN000;
ASSUME	DS:NOTHING,ES:NOTHING,SS:NOTHING						 ;AN000;
											 ;AN000;
; Perform initialization at DOSINIT time						 ;AN000;
											 ;AN000;
	PUSH	DS									 ;AN000;
	PUSH	ES									 ;AN000;
	PUSH	SI									 ;AN000;
	PUSH	DI									 ;AN000;
	PUSH	DX									 ;AN000;
	PUSH	CX									 ;AN000;
	PUSH	BX									 ;AN000;
	PUSH	AX									 ;AN000;
	PUSH	CS									 ;AN000;
	POP	DS									 ;AN000;
											 ;AN000;
ASSUME	DS:IFSSEG									 ;AN000;
											 ;AN000;
; SET INTERRUPT VECTORS 								 ;AN000;
											 ;AN000;
	MOV	AL,2FH									 ;AN000;
	PUSH	AX									 ;AN000;
	MOV	AX,(multDOS SHL 8) OR 2 						 ;AN000;
	INT	2FH									 ;AN000;
	POP	AX				; no know contents			 ;AN000;
											 ;AN000;
	PUSH	ES									 ;AN000;
	PUSH	BX									 ;AN000;
	LES	BX,DWORD PTR ES:[BX]		; setting int 2f mult 5 		 ;AN000;
	MOV	WORD PTR [NEXT_2F_5],BX 						 ;AN000;
	MOV	WORD PTR [NEXT_2F_5+2],ES						 ;AN000;
	POP	BX									 ;AN000;
	POP	ES									 ;AN000;
											 ;AN000;
	MOV	DX,OFFSET INT_2F_5							 ;AN000;
	MOV	ES:[BX],DX								 ;AN000;
	MOV	ES:[BX+2],DS								 ;AN000;
											 ;AN000;
	MOV	AX,(Get_Interrupt_Vector SHL 8) + 2Fh					 ;AN000;
	INT	21h									 ;AN000;
	MOV	WORD PTR CONT,BX							 ;AN000;
	MOV	WORD PTR CONT+2,ES							 ;AN000;
	MOV	AX,(Set_Interrupt_Vector SHL 8) + 2Fh					 ;AN000;
	MOV	DX,OFFSET INT2F 		; multIFS handler			 ;AN000;
	INT	21h									 ;AN000;
;											 ;AN000;
; auto - attach 									 ;AN000;
;											 ;AN000;
	CALL	AUTO_ATTACH								 ;AN000;
;											 ;AN000;
; call swap setup									 ;AN000;
;											 ;AN000;
	PUSH	DS									 ;AN000;
	MOV	AX,(multDOS SHL 8) OR 3 						 ;AN000;
	INT	2FH									 ;AN000;
ASSUME	DS:DOSGROUP									 ;AN000;
	invoke	SERVER_IFSFUNC_DATA_AREA						 ;AN000;
	POP	DS									 ;AN000;
	invoke	SET_IFS_DOSCALL@							 ;AN003;
											 ;AN000;
	PUSH	CS									 ;AN000;
	POP	ES									 ;AN000;
;											 ;AN007;
; Prep error messages									 ;AN007;
;											 ;AN007;
	LEA	DI,Rods_label								 ;AN007;
	SaveReg <CS>									 ;AN007;
	RestoreReg <ES> 								 ;AN007;
	MOV	AX,DOS_GET_EXT_PARSE_ADD						 ;AN007;
	MOV	DL,7				; set msg addr				 ;AN007;
	INT	2FH									 ;AN007;
;											 ;AN000;
; Now start clobbering code								 ;AN000;
;											 ;AN000;
	MOV	DI,OFFSET NETEND		; Start strucs here			 ;AN000;
	TEST	DI,1				; Word aligned? 			 ;AN000;
	JZ	IF_20				; Yes, ok				 ;AN000;
	INC	DI				; Bump to word align			 ;AN000;
IF_20:						; NOADJ1				 ;AN000;
	JMP	IF_40				; jmp CONTIFSINIT			 ;AN000;
											 ;AN000;
EndProc IFSFINIT									 ;AN000;
											 ;AN000;
;************* ifsfuncinit transient portion ******************************		 ;AN000;
       AA_PARMS_BUF DB 6 DUP(0) 		; temp storage used by auto-attach	 ;AN000;
       S_SIZE1	DB 11				; Sublist size(PTR next SUBLIST)	 ;AN000;
		DB 0				; Reserved				 ;AN000;
		DD SUB_IFSFUNC			; Ptr to substituted string		 ;AN000;
		DB  1				; n of %n				 ;AN000;
		DB Left_Align+Char_Field_ASCIIZ ; Data-type flags			 ;AN000;
		DB 7				; Maximum field width			 ;AN000;
		DB 5				; Minimum field width			 ;AN000;
		DB " "                          ; Character for Pad field                ;AN000;
       S_SIZE2	DB 11				; Sublist size(PTR next SUBLIST)	 ;AN000;
		DB 0				; Reserved				 ;AN000;
		DD SUB_SHARE			; Ptr to substituted string		 ;AN000;
		DB  1				; n of %n				 ;AN000;
		DB Left_Align+Char_Field_ASCIIZ ; Data-type flags			 ;AN000;
		DB 7				; Maximum field width			 ;AN000;
		DB 5				; Minimum field width			 ;AN000;
		DB " "                          ; Character for Pad field                ;AN000;
											 ;AN000;
SUB_IFSFUNC	DB	"IFSFUNC",0                                                      ;AN000;
SUB_SHARE	DB	"SHARE",0                                                        ;AN000;
											 ;AN000;
DEFAULT_DFLCount DB	4								 ;AN000;
;;;alias DEFAULT_NLSize   DW	 172			 ; 4 * 43			 ;AN000;
											 ;AN000;
	ASSUME	CS:IFSSEG,DS:NOTHING							 ;AN000;
.xlist											 ;AN000;
.xcref											 ;AN000;
	INCLUDE IFSPARSE.INC								 ;AN000;

 public amis_sign
	even
amis_sign:
	db "ecm"
	db 5 dup (' ')
	db "lDOS"
	db 4 dup (' ')
amis_id:			; must be directly after amis_sign
	dw 0
	dw 0			; sequential number
	db amis_id_msg_end - amis_id_msg
amis_id_msg:
	db "ifsfunc"		; our id name
amis_id_msg_end:

AMIS_SIGN_SEGMENT equ IFSSEG

	msg_services <DISPLAYmsg,CHARmsg,LOADmsg>					 ;AN000;
	msg_services <ifsfunc.cla,ifsfunc.cl2>	; parse/install msgs			 ;AN000;
.cref											 ;AN000;
.list											 ;AN000;
											 ;AN000;
;****************************************************************************** 	 ;AN000;
;		!!!!!!!   IFSFUNC starts here	!!!!!!! 	(see END statement)	 ;AN000;
;****************************************************************************** 	 ;AN000;
											 ;AN000;
IFSFUNCINIT:										 ;AN000;
											 ;AN000;
	CALL	SYSLOADMSG								 ;AN000;
	JNC	I_20									 ;AN000;
	SaveReg <CS>									 ;AN006;
	RestoreReg <DS> 								 ;AN006;
	CALL	SYSDISPMSG								 ;AN000;
											 ;AN000;
Badver_msg proc    far									 ;AN000;
	MOV	AL,0FFh 								 ;AN000;
	SaveReg <CS>									 ;AN000;
	RestoreReg <DS> 								 ;AN000;
	MOV	AH,EXIT 								 ;AN000;
	INT	21h									 ;AN000;
	PUSH	ES									 ;AN000;
	XOR	AX,AX									 ;AN000;
	PUSH	AX									 ;AN000;
	RET										 ;AN000;
badver_msg  ENDP									 ;AN000;
											 ;AN000;
Badmes	proc	far									 ;AN000;
	ASSUME	CS:IFSSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING				 ;AN000;
	MOV	BX,STDERR								 ;AN000;
	XOR	DL,DL									 ;AN000;
	CALL	SYSDISPMSG								 ;AN000;
	MOV	AX,(EXIT SHL 8) + 0FFH							 ;AN000;
	INT	21h									 ;AN000;
badmes	ENDP										 ;AN000;
											 ;AN000;
											 ;AN000;
I_20:						; Version OK				 ;AN000;
	MOV	AX,(multIFS SHL 8)+0		; Check if IFSFUNC already installed	 ;AN000;
	INT	2Fh									 ;AN000;
	CMP	AL,0									 ;AN000;
	JE	I_40									 ;AN000;
	MOV	AX,COMMON_ERR_2 		; yes - already installed - error 2	 ;AN000;
	PUSH	CS									 ;AN000;
	POP	DS									 ;AN000;
	MOV	SI,OFFSET S_SIZE1		;	prep for sysdispmsg call	 ;AN000;
	MOV	CX,1									 ;AN000;
	MOV	DH,UTILITY_MSG_CLASS							 ;AN000;
I_30:											 ;AN005;
	PUSH	CS									 ;AN000;
	POP	DS									 ;AN000;
	JMP	BADMES									 ;AN000;
						; no error on install check,		 ;AN000;
I_40:						; free environment - no longer needed	 ;AN000;
	MOV	AX,DS:[PDB_ENVIRON]							 ;AN000;
	OR	AX,AX									 ;AN000;
	JZ	I_60									 ;AN000;
	PUSH	ES									 ;AN000;
	MOV	ES,AX									 ;AN000;
	MOV	AH,DEALLOC								 ;AN000;
	INT	21H									 ;AN000;
	POP	ES									 ;AN000;
I_60:											 ;AN000;
;************************************************************************************	 ;AN000;
;	Parse IFSFUNC parameter :							 ;AN000;
;		   NAMES = n		 ;;;alias[n | (n {m})]				 ;AN000;
;************************************************************************************	 ;AN000;
						; Set default n and m			 ;AN000;
	MOV	AL,DEFAULT_DFLCount							 ;AN000;
	MOV	[DFLCount],AL			; 4	   (n)				 ;AN000;
;;;aliasMOV	AX,DEFAULT_NLSize							 ;AN000;
;;;aliasMOV	NLSize,AX			; 4 * 43   (m)				 ;AN000;
											 ;AN000;
	MOV	SI,81h				; ds:si -> cmd parameter		 ;AN000;
	XOR	CX,CX				; no operands parsed yet		 ;AN000;
	PUSH	CS									 ;AN000;
	POP	ES									 ;AN000;
ASSUME	ES:IFSSEG									 ;AN000;
	MOV	DI,OFFSET IFSF_PARMS		; es:di -> parse control blocks 	 ;AN000;
	XOR	DX,DX				; reserved				 ;AN000;
											 ;AN000;
	CALL	SYSPARSE			; call parser				 ;AN000;
											 ;AN000;
	CMP	AX,-1				; End of cmd?				 ;AN000;
	JNE	I_70									 ;AN000;
	JMP	I_160				;    if so continue w/init		 ;AN000;
I_70:											 ;AN000;
	CMP	AX,0				; Error?				 ;AN000;
	JNE	I_140				;    yes - go display parse error	 ;AN000;
											 ;AN000;
;;;aliasCMP	IFSF_RESULT,COMPLEX		; complex?				 ;AN000;
;;;aliasJE	I_80									 ;AN000;
	CMP	IFSF_TAG,"N"                    ;   no - n only                          ;AN000;
	MOV	AX,PARSE_ERR_6								 ;AN002;
	JNE	I_140									 ;AN000;
											 ;AN000;
	MOV	AL,IFSF_NM								 ;AN000;
	MOV	[DFLCount],AL								 ;AN000;
											 ;AN000;
	CALL	SYSPARSE								 ;AN000;
	CMP	AX,-1									 ;AN000;
	JE	I_160									 ;AN000;
	MOV	AX,PARSE_ERR_1								 ;AN000;
;;;aliasJMP	I_140				; go display parse error		 ;AN000;
;;;											 ;AN000;
;;;aliasI_80:					; process complex  (n,m)		 ;AN000;
;;;	XOR	CX,CX				; prep for new parse call		 ;AN000;
;;;	XOR	DX,DX									 ;AN000;
;;;	CALL	SYSPARSE								 ;AN000;
;;;	CMP	AX,-1				; End of cmd?				 ;AN000;
;;;	JE	I_160				;    if so continue w/init		 ;AN000;
;;;	CMP	AX,0				; Error?				 ;AN000;
;;;	JNE	I_140				;    if so go display error		 ;AN000;
;;;	CMP	IFSF_TAG,"N"                    ; check if n or m parm                   ;AN000;
;;;	JNE	I_100									 ;AN000;
;;;	MOV	AL,IFSF_NM			; n parm				 ;AN000;
;;;	MOV	DFLCount,AL								 ;AN000;
;;;	CALL	SYSPARSE			; go back for m 			 ;AN000;
;;;	CMP	AX,-1				; End of cmd?				 ;AN000;
;;;	JE	I_160				;    if so continue w/init		 ;AN000;
;;;	CMP	AX,0				; Error?				 ;AN000;
;;;	JNE	I_140				;    if so go display error		 ;AN000;
;;;											 ;AN000;
;;;00:											 ;AN000;
;;;	CMP	IFSF_TAG,"M"                    ; check if m parm                        ;AN000;
;;;	JE	I_120									 ;AN000;
;;;	MOV	AX,PARSE_ERR_7			; not m - error 			 ;AN002;
;;;	JMP	I_140									 ;AN000;
;;;20:											 ;AN000;
;;;	MOV	AX,WORD PTR IFSF_NM		; m parm				 ;AN000;
;;;	MOV	NLSize,AX								 ;AN000;
;;;											 ;AN000;
;;;	CALL	SYSPARSE			; call parser again to check for	 ;AN000;
;;;	CMP	AX,-1				; possible garbage			 ;AN000;
;;;	JE	I_160									 ;AN000;
;;;	MOV	AX,PARSE_ERR_1								 ;AN000;
;;;alias										 ;AN000;
I_140:						; display parse error			 ;AN000;
	MOV	DH,PARSE_ERR_CLASS		; then continue w/defaults		 ;AN000;
	XOR	CX,CX									 ;AN000;
;;;	MOV	BX,STDERR								 ;AD005;
;;;	XOR	DL,DL									 ;AD005;
;;;	CALL	SYSDISPMSG								 ;AD005;
	JMP	I_30									 ;AN005;
											 ;AN000;
I_160:											 ;AN000;
						; doinit				 ;AN000;
	MOV	AX,DS				; Move the stack so it doesn't           ;AN000;
						; get blasted by structure init 	 ;AN000;
	MOV	SS,AX				; Set stack in the PSP overlaying	 ;AN000;
	MOV	SP,100H 			; parms just processed			 ;AN000;
;											 ;AN000;
; We must now do some computation. We have to check if there is enough room		 ;AN000;
;  for everything. We must do this here BEFORE we start overlaying this 		 ;AN000;
;  code 										 ;AN000;
;											 ;AN000;
	PUSH	CS									 ;AN000;
	POP	DS									 ;AN000;
ASSUME	DS:IFSSEG									 ;AN000;
											 ;AN000;
	MOV	DI,OFFSET NETEND		; We have this much code		 ;AN000;
	TEST	DI,1				; Word aligned? 			 ;AN000;
	JZ	I_180				; Yes, OK.				 ;AN000;
	INC	DI				; Make word aligned			 ;AN000;
I_180:						; no adjust 5 label			 ;AN000;
											 ;AN000;
; This code is added to make it easy to determine the code size 			 ;AN000;
; of IFSFUNC for debug purposes. It is overlayed, so does not use extra 		 ;AN000;
; storage.										 ;AN000;
	PUSH	DI		       ;						 ;AN000;
	PUSH	SI		       ;						 ;AN000;
	LEA	SI,CODESIZE+3	       ;						 ;AN000;
I_200:				       ; TENT						 ;AN000;
	SUB	DI,10000	       ;						 ;AN000;
	JC	I_220		       ;						 ;AN000;
	INC	BYTE PTR [SI]	       ;						 ;AN000;
	JMP	I_200		       ;						 ;AN000;
I_220:				       ; NEG1						 ;AN000;
	ADD	DI,10000	       ;						 ;AN000;
	INC	SI		       ;						 ;AN000;
I_240:				       ; THOU						 ;AN000;
	SUB	DI,1000 	       ;						 ;AN000;
	JC	I_260		       ;						 ;AN000;
	INC	BYTE PTR [SI]	       ;						 ;AN000;
	JMP	I_240		       ;						 ;AN000;
I_260:				       ; NEG2						 ;AN000;
	ADD	DI,1000 	       ;						 ;AN000;
	INC	SI		       ;						 ;AN000;
I_280:				       ; HUND						 ;AN000;
	SUB	DI,100		       ;						 ;AN000;
	JC	I_300		       ;						 ;AN000;
	INC	BYTE PTR [SI]	       ;						 ;AN000;
	JMP	I_280		       ;						 ;AN000;
I_300:				       ; NEG3						 ;AN000;
	ADD	DI,100		       ;						 ;AN000;
	INC	SI		       ;						 ;AN000;
I_320:				       ; TENS						 ;AN000;
	SUB	DI,10		       ;						 ;AN000;
	JC	I_340		       ;						 ;AN000;
	INC	BYTE PTR [SI]	       ;						 ;AN000;
	JMP	I_320		       ;						 ;AN000;
I_340:				       ; NEG4						 ;AN000;
	ADD	DI,10		       ;						 ;AN000;
	INC	SI		       ;						 ;AN000;
I_360:				       ; ONES						 ;AN000;
	SUB	DI,1		       ;						 ;AN000;
	JC	I_380		       ;						 ;AN000;
	INC	BYTE PTR [SI]	       ;						 ;AN000;
	JMP	I_360		       ;						 ;AN000;
I_380:				       ; DONE						 ;AN000;
	POP	SI		       ;						 ;AN000;
	POP	DI		       ;						 ;AN000;
;											 ;AN000;
; Allocate the DFL									 ;AN000;
;											 ;AN000;
	MOV	AL,DFLCount								 ;AN000;
	XOR	AH,AH									 ;AN000;
	MOV	CX,SIZE DFLL_LIST							 ;AN000;
	MUL	CX									 ;AN000;
	OR	DX,DX									 ;AN000;
	JZ	I_402									 ;AN000;
	JMP	I_640				; out of memp				 ;AN000;
I_402:											 ;AN000;
	ADD	DI,AX									 ;AN000;
	JNC	I_403									 ;AN000;
	JMP	I_640				; out of memp				 ;AN000;
I_403:											 ;AN000;
;;;aliasADD	DI,NLSIZE								 ;AN000;
;;;aliasJNC	I_404									 ;AN000;
;;;aliasJMP	I_640				; out of memp				 ;AN000;
I_404:											 ;AN000;
	CALL	CHECK_UNC_PRESENCE		; check if unc present, if not, 	 ;AN000;
	TEST	IFSFUNC_FLAGS,UNC_INSTALLED						 ;AN000;
	JZ	I_415				; no need to allocate altcds		 ;AN000;
;											 ;AN000;
; Allocate the TEMP CDS area								 ;AN000;
;											 ;AN000;
	PUSH	DS									 ;AN000;
	MOV	AX,(multDOS SHL 8) OR 3 						 ;AN000;
	INT	2FH									 ;AN000;
ASSUME	DS:DOSGROUP									 ;AN000;
	MOV	CL,CDSCount								 ;AN000;
	XOR	CH,CH									 ;AN000;
	INC	CX									 ;AN000;
	MOV	AX,SIZE curdir_list							 ;AN000;
	MUL	CX									 ;AN000;
	OR	DX,DX									 ;AN000;
	JZ	I_410									 ;AN000;
	JMP	I_640									 ;AN000;
I_410:											 ;AN000;
	ADD	DI,AX				; Temp CDS area 			 ;AN000;
	JNC	I_417									 ;AN000;
	JMP	I_640									 ;AN000;
I_415:											 ;AN000;
;											 ;AN000;
; Determine if need new FCB cache and Allocate it if appropriate			 ;AN000;
;											 ;AN000;
	PUSH	DS				; get addressability to DOSGROUP	 ;AN000;
	MOV	AX,(multDOS SHL 8) OR 3 						 ;AN000;
	INT	2FH									 ;AN000;
ASSUME	DS:DOSGROUP									 ;AN000;
I_417:											 ;AN000;
	CMP	KeepCount,DefKeepVal							 ;AN000;
	JNZ	I_420									 ;AN000;
	LDS	SI,SFTFCB								 ;AN000;
ASSUME	DS:NOTHING									 ;AN000;
	CMP	[SI].sfCount,DefNumFCB							 ;AN000;
	JNZ	I_420									 ;AN000;
	INC	NEWFCBCACHE			; Flag ourselves			 ;AN000;
	ADD	DI,((SIZE sf_entry) * NewNumFCB)+((SIZE sf)-2) ; New cache		 ;AN000;
	JC	I_640				; out of memp				 ;AN000;
I_420:						; no fcb				 ;AN000;
	POP	DS									 ;AN000;
ASSUME	DS:IFSSEG									 ;AN000;
											 ;AN000;
; This code is added to make it easy to determine the total size	   @A1A 	 ;AN000;
; of IFSFUNC.	      It is overlayed, so does not use extra storage.	   @A1A 	 ;AN000;
					;				   @A1A 	 ;AN000;
	PUSH	DI			;				   @A1A 	 ;AN000;
	PUSH	SI			;				   @A1A 	 ;AN000;
	LEA	SI,TOTSIZE		;				   @A1A 	 ;AN000;
I_440:					; TENT2 			   @A1A 	 ;AN000;
	SUB	DI,10000		;				   @A1A 	 ;AN000;
	JC	I_460			;				   @A1A 	 ;AN000;
	INC	BYTE PTR [SI]		;				   @A1A 	 ;AN000;
	JMP	I_440			;				   @A1A 	 ;AN000;
I_460:					; NEG5				   @A1A 	 ;AN000;
	ADD	DI,10000		;				   @A1A 	 ;AN000;
	INC	SI			;				   @A1A 	 ;AN000;
I_480:					; THOU2 			   @A1A 	 ;AN000;
	SUB	DI,1000 		;				   @A1A 	 ;AN000;
	JC	I_500			;				   @A1A 	 ;AN000;
	INC	BYTE PTR [SI]		;				   @A1A 	 ;AN000;
	JMP	I_480			;				   @A1A 	 ;AN000;
I_500:					; NEG6				   @A1A 	 ;AN000;
	ADD	DI,1000 		;				   @A1A 	 ;AN000;
	INC	SI			;				   @A1A 	 ;AN000;
I_520:					; HUND2 			   @A1A 	 ;AN000;
	SUB	DI,100			;				   @A1A 	 ;AN000;
	JC	I_540			;				   @A1A 	 ;AN000;
	INC	BYTE PTR [SI]		;				   @A1A 	 ;AN000;
	JMP	I_520			;				   @A1A 	 ;AN000;
I_540:					; NEG7				   @A1A 	 ;AN000;
	ADD	DI,100			;				   @A1A 	 ;AN000;
	INC	SI			;				   @A1A 	 ;AN000;
I_560:					; TENS2 			   @A1A 	 ;AN000;
	SUB	DI,10			;				   @A1A 	 ;AN000;
	JC	I_580			;				   @A1A 	 ;AN000;
	INC	BYTE PTR [SI]		;				   @A1A 	 ;AN000;
	JMP	I_560			;				   @A1A 	 ;AN000;
I_580:					; NEG8				   @A1A 	 ;AN000;
	ADD	DI,10			;				   @A1A 	 ;AN000;
	INC	SI			;				   @A1A 	 ;AN000;
I_600:					; ONES2 			   @A1A 	 ;AN000;
	SUB	DI,1			;				   @A1A 	 ;AN000;
	JC	I_620			;				   @A1A 	 ;AN000;
	INC	BYTE PTR [SI]		;				   @A1A 	 ;AN000;
	JMP	I_600			;				   @A1A 	 ;AN000;
I_620:					; DONE2 			   @A1A 	 ;AN000;
	POP	SI			;				   @A1A 	 ;AN000;
	POP	DI			;				   @A1A 	 ;AN000;
											 ;AN000;
											 ;AN000;
	JMP	I_700									 ;AN000;
											 ;AN000;
I_640:					; OUT_OF_MEMP					 ;AN000;
	POP	DS									 ;AN000;
I_660:					; OUT_OF_MEM					 ;AN000;
	MOV	AX,PARSE_ERR_10 							 ;AN000;
	XOR	CX,CX									 ;AN000;
	JMP	BADMES									 ;AN000;
											 ;AN000;
ASSUME	DS:NOTHING									 ;AN000;
											 ;AN000;
											 ;AN000;
BREAK <AUTO_ATTACH -- Attempt attaches of non-FAT physical drives>			 ;AN000;
											 ;AN000;
;************************************************************************************	 ;AN000;
;											 ;AN000;
; AUTO_ATTACH										 ;AN000;
;											 ;AN000;
; Called by: init									 ;AN000;
;											 ;AN000;
; Routines called:  CALL_IFS								 ;AN000;
;		    CDS_TO_CD								 ;AN000;
;		    CD_TO_CDS								 ;AN000;
;		    FIND_IFS_DRIVER							 ;AN000;
; Inputs:										 ;AN000;
;	None										 ;AN000;
;											 ;AN000;
; Function:										 ;AN000;
;	Get addressability to CDS structure  (SYSVARS - IBMDOS/BIO)			 ;AN000;
;	FOR I = 1 to # CDS								 ;AN000;
;	   DO										 ;AN000;
;	   ³   Drive = I - 1  (0-A,1-B,...)						 ;AN000;
;	   ³   IF (curdir_inuse == 0 & curdir_devptr .NOT. 0) THEN			 ;AN000;
;	   ³	   DO									 ;AN000;
;	   ³	   ³   Get pointer to 1st IFS header					 ;AN000;
;	   ³	   ³   WHILE pointer .NOT. 0FFFFH					 ;AN000;
;	   ³	   ³	   DO								 ;AN000;
;	   ³	   ³	       START ATTACH						 ;AN000;
;	   ³	   ³		   (IFSR_TYPE	=  2					 ;AN000;
;	   ³	   ³		    IFSR_PARMS@ -> IFS name, 0 parms)			 ;AN000;
;	   ³	   ³	       IF Attach successful THEN				 ;AN000;
;	   ³	   ³		  DO							 ;AN000;
;	   ³	   ³		    IF IFSUSESHARE set THEN				 ;AN000;
;	   ³	   ³		       Set share flag					 ;AN000;
;	   ³	   ³		    ENDIF						 ;AN000;
;	   ³	   ³		    LEAVE While 					 ;AN000;
;	   ³	   ³		  ENDDO 						 ;AN000;
;	   ³	   ³	       ELSE							 ;AN000;
;	   ³	   ³		   Get pointer to next IFS header			 ;AN000;
;	   ³	   ³	       ENDIF							 ;AN000;
;	   ³	   ³	   ENDDO							 ;AN000;
;	   ³	   ³   ENDWHILE 							 ;AN000;
;	   ³	   ENDDO								 ;AN000;
;	   ³   ENDIF									 ;AN000;
;	   ENDDO									 ;AN000;
;	IF Share flag set THEN								 ;AN000;
;	   DO										 ;AN000;
;	     IF SHARE .NOT. loaded  THEN						 ;AN000;
;		issue warning msg:  "SHARE not loaded"  using msg retriever              ;AN000;
;	   END										 ;AN000;
;	ENDIF										 ;AN000;
;											 ;AN000;
; Outputs: Successful auto-attachments in effect					 ;AN000;
;											 ;AN000;
;************************************************************************************	 ;AN000;
											 ;AN000;
	Procedure   AUTO_ATTACH,NEAR							 ;AN000;
ASSUME	DS:NOTHING,ES:NOTHING								 ;AN000;
											 ;AN000;
	TEST	IFSFUNC_FLAGS,NO_IFS_DRIVERS						 ;AN000;
	JZ	AA_05									 ;AN000;
	JMP	AA_1000 								 ;AN000;
											 ;AN000;
AA_05:											 ;AN000;
	SaveReg <DS,ES,DI>			; preserve ds - psp,es di storage	 ;AN000;
	ifsr_fcn_def  ATTSTART								 ;AN000;
	MOV	CS:IFSPROC_FLAGS,THISIFS_SET+IsInit ; set this so that cds_to_cd doesn't ;AC010;
						; set thisifs				 ;AN000;
											 ;AN000;
	MOV	AH,Get_In_Vars			; Get ptr to ifs hdr chain		 ;AN000;
	INT	21h				; es:bx -> sysinitvars			 ;AN000;
	LES	DI,ES:[BX.SYSI_IFS]		; es:di -> 1st ifs driver		 ;AN000;
											 ;AN000;
	MOV	AX,(multDOS SHL 8) OR 3 	; get addressability to dosgroup	 ;AN000;
	INT	2FH									 ;AN000;
ASSUME	DS:DOSGROUP									 ;AN000;
											 ;AN000;
	MOV	CL,[CDSCount]			; prep cds loop 			 ;AN000;
	XOR	CH,CH									 ;AN000;
	MOV	DX,SIZE CURDIR_LIST							 ;AN000;
	LDS	SI,[CDSAddr]			; ds:si -> CDS list			 ;AN000;
ASSUME	DS:NOTHING									 ;AN000;
											 ;AN000;
AA_10:						; ** Loop here on cds entries		 ;AN000;

	TEST	DS:[SI.CURDIR_FLAGS],CURDIR_INUSE ;  check for ifs-able drive		 ;AN000;
	JZ	AA_13									 ;AN000;
	JMP	AA_120				;    cds already inuse, try next cds	 ;AN000;
AA_13:											 ;AN000;
	CMP	WORD PTR DS:[SI.CURDIR_DEVPTR],0					 ;AN000;
	JNZ	AA_16									 ;AN000;
	CMP	WORD PTR DS:[SI.CURDIR_DEVPTR+2],0					 ;AN000;
	JNZ	AA_16									 ;AN000;
	JMP	AA_120				;    cds not real, try next cds 	 ;AN000;
AA_16:											 ;AN000;
	MOV	AX,SI				;    attempt				 ;AN000;
	SaveReg <DS,AX> 			; cds seg, offset			 ;AN000;
	MOV	AX,(multDOS SHL 8) OR 3 	; get dosgroup in ds to access cdsaddr	 ;AN000;
	INT	2FH									 ;AN000;
ASSUME	DS:DOSGROUP									 ;AN000;
	RestoreReg <AX> 			; cds offset				 ;AN000;
	SUB	AX,WORD PTR [CDSADDR]		; get  drive # (0-based) in al		 ;AN000;
	MOV	BL,SIZE CurDir_list							 ;AN000;
	DIV	BL									 ;AN000;
	RestoreReg <DS> 			; cds segment				 ;AN000;
	SaveReg <AX>				; drive # (0-based 0=A) 		 ;AN000;
	MOV	BL,AL									 ;AN000;
	INC	BL				; change to 1-based (1=A)		 ;AN000;
	MOV	AX,CHECK_REMOVABLE		; 4408H (device ioctl)			 ;AN000;
	INT	21H									 ;AN000;
	OR	AX,AX				; ax 0 - drive removable		 ;AN000;
	RestoreReg <AX> 			; drive # (0-based)			 ;AN000;
	JNZ	AA_19									 ;AN000;
	JMP	AA_120				; drive removable, don't auto-attach     ;AN000;
											 ;AN000;
AA_19:						;    cds ok, proceed with autoattach	 ;AN000;
	CBW					; convert al to word (ax)		 ;AN000;
	MOV	BL,10									 ;AN000;
	DIV	BL				; convert number (ex.14) to char	 ;AN000;
	ADD	AX,3030H			; (3134) (ah-remain,al-quot)		 ;AN000;
											 ;AN000;
	SaveReg <ES,DI> 			; Save 1st ifs driver			 ;AN000;
	MOV	CS:WORD PTR [THISIFS],DI	; Send attach start request		 ;AN000;
	MOV	CS:WORD PTR [THISIFS+2],ES	; to all fs drivers.  Stop when 	 ;AN000;
						; one clicks.				 ;AN000;
AA_20:											 ;AN000;
	SaveReg <ES,DI,CX,DX,DS,SI>		; ifs ptr, cds count-size-ptr		 ;AN000;
											 ;AN000;
	SaveReg <AX,DS> 			; get ES -> dosgroup (save char drv#)	 ;AN000;
	MOV	AX,(multDOS SHL 8) OR 3 						 ;AN000;
	INT	2FH									 ;AN000;
	SaveReg <DS>									 ;AN000;
	RestoreReg <ES> 								 ;AN000;
ASSUME	DS:DOSGROUP,ES:DOSGROUP 							 ;AN000;
						; do attach w/dummy cds so as not	 ;AN000;
	MOV	DI,OFFSET DOSGROUP:DummyCDS		 ; to ruin valid cds		 ;AN000;
	RestoreReg <DS> 								 ;AN000;
ASSUME	DS:NOTHING									 ;AN000;
	PUSH	DI									 ;AN000;
	MOV	CX,SIZE curdir_list							 ;AN000;
	REP	MOVSB									 ;AN000;
	PUSH	ES									 ;AN000;
	POP	DS									 ;AN000;
	POP	SI		; DS:SI -> dummy CDS					 ;AN000;
	MOV	[SI.curdir_flags],curdir_isifs + curdir_inuse				 ;AN000;
	MOV	[SI.curdir_type],type_drive						 ;AN000;
	MOV	AX,WORD PTR CS:[THISIFS]						 ;AN000;
	MOV	WORD PTR [SI.CURDIR_IFS_HDR],AX 					 ;AN000;
	MOV	AX,WORD PTR CS:[THISIFS+2]						 ;AN000;
	MOV	WORD PTR [SI.CURDIR_IFS_HDR+2],AX					 ;AN000;
	RestoreReg <AX> 			; char drive #				 ;AN000;
	SaveReg <DS,SI> 			; dummy cds ptr 			 ;AN000;
											 ;AN000;
	invoke	PREP_IFSR			; sets es:bx -> ifsr, 0s fields,	 ;AN000;
						; ds - ifsseg				 ;AN000;
	MOV	DEVICE_CB@_OFFSET,IFSR_DEVICE_CB@					 ;AN000;
	invoke	CDS_TO_CD			; sets ifsr_device_cb@			 ;AN000;
	MOV	ES:[BX.IFSR_LENGTH],LENGTH_ATTSTART					 ;AN000;
	MOV	ES:[BX.IFSR_FUNCTION],IFSATTSTART					 ;AN000;
	MOV	ES:[BX.IFSR_TYPE],TYPE_DRIVE						 ;AN000;
											 ;AN000;
	MOV	SI,OFFSET AA_PARMS_BUF		; set up attach parameter buffer	 ;AN000;
	MOV	WORD PTR DS:[SI],1		; in tempbuf = dw 1			 ;AN000;
	MOV	WORD PTR DS:[SI+2],AX		;	       db 3134,0		 ;AN000;
	XOR	AL,AL									 ;AN000;
	MOV	BYTE PTR DS:[SI+4],AL		; asciiz				 ;AN000;
	MOV	WORD PTR ES:[BX.IFSR_PARMS@],SI 					 ;AN000;
	MOV	WORD PTR ES:[BX.IFSR_PARMS@+2],DS					 ;AN000;
											 ;AN000;
AA_40:						; ** Loop here on ifs drivers		 ;AN000;
	invoke	CALL_IFS			; call ifs driver w/attach start req	 ;AN000;
											 ;AN000;
	JC	AA_60				; jmp on no click			 ;AN000;
						; click:				 ;AN000;
	RestoreReg <DI,ES>			; restore cds ptr to es:di		 ;AN000;
	invoke	CD_TO_CDS			; update cds entry			 ;AN000;
	SaveReg <ES>				; move dummy cds ptr back to ds:si	 ;AN000;
	RestoreReg <DS> 								 ;AN000;
	MOV	SI,DI				; ds:si -> dummy cds			 ;AN000;
	RestoreReg <DI,ES>			; es:di -> real cds			 ;AN000;
	MOV	CX,SIZE CURDIR_LIST		; copy dummy into real - ok to		 ;AN000;
	SaveReg <DI>									 ;AN000;
	OR	DS:[SI.CURDIR_FLAGS],CURDIR_ISIFS  ; set this cds as ifs		 ;AN009;
	REP	MOVSB				; clobber now				 ;AN000;
	RestoreReg <SI> 			; move real cds ptr back to ds:si	 ;AN000;
	SaveReg <ES>									 ;AN000;
	RestoreReg <DS> 								 ;AN000;
	RestoreReg <DX,CX,DI,ES>		; restore cds size, count,		 ;AN000;
						;	  ifs ptr			 ;AN000;
	TEST	CS:IFSPROC_FLAGS,ISSHARE	; check if share checked		 ;AN000;
	JNZ	AA_100				; go process next cds			 ;AN000;
	TEST	ES:[DI.IFS_ATTRIBUTE],IFSUSESHARE					 ;AN000;
	JZ	AA_100				; ifs driver needs share		 ;AN000;
;; D526   CallInstall SHAREInstall,multSHARE,0	  ;   check that share loaded		   ;AN000;
	CallInstall SHAREInstall,multSHARE,40H	;   check that share loaded		 ;AN013;
	CMP	AL,INSTALLED			;   if not generate warning		 ;AN000;
	JE	AA_50									 ;AN000;
	SaveReg <DS,SI,CX,DX>								 ;AN000;
	MOV	AX,COMMON_ERR_3 		; "SHARE not installed"                  ;AN000;
	PUSH	CS									 ;AN000;
	POP	DS									 ;AN000;
	MOV	SI,OFFSET S_SIZE2							 ;AN000;
	MOV	CX,1									 ;AN000;
	MOV	DH,UTILITY_MSG_CLASS							 ;AN000;
	MOV	BX,STDERR								 ;AN000;
	XOR	DL,DL									 ;AN000;
	CALL	SYSDISPMSG								 ;AN000;
	RestoreReg <DX,CX,SI,DS>							 ;AN000;
											 ;AN000;
AA_50:											 ;AN000;
	OR	CS:IFSPROC_FLAGS,ISSHARE	; set this so won't check share again    ;AN000;
	JMP	AA_100									 ;AN000;
											 ;AN000;
AA_60:						; ** Next driver			 ;AN000;
	RestoreReg <AX,BX>			; dummy cds ptr 			 ;AN000;
	RestoreReg <SI,DS,DX,CX,DI,ES>		; restore: ifs and cds ptrs,		 ;AN000;
						;	   cds count and size		 ;AN000;
	LES	DI,ES:[DI.IFS_NEXT]		; check next fs driver			 ;AN000;
	CMP	DI,NULL_PTR			; if ptr null, end of ifs drivers	 ;AN000;
	JNE	AA_80									 ;AN000;
	PUSH	AX				; dummy cds offset			 ;AN000;
	MOV	AX,ES									 ;AN000;
	CMP	AX,NULL_PTR								 ;AN000;
	POP	AX				; dummy cds offset			 ;AN000;
	JE	AA_100				; go process next cds if no more ifs	 ;AN000;
AA_80:											 ;AN000;
	MOV	CS:WORD PTR [THISIFS],DI	; prep next ifs driver			 ;AN000;
	MOV	CS:WORD PTR [THISIFS+2],ES						 ;AN000;
	SaveReg <ES,DI,CX,DX,DS,SI>		; Save regs				 ;AN000;
	SaveReg <AX,BX> 			; dummy cds ptr 			 ;AN000;
	SaveReg <CS,CS> 			; get esdi back to ifsrh		 ;AN008;
	RestoreReg <ES,DS>			; and ds-ifsseg 			 ;AN008;
	MOV	BX,OFFSET IFSR								 ;AN008;
	XOR	AX,AX									 ;AN008;
	MOV	ES:[BX.IFSR_RETCODE],AX 	; restore error fields			 ;AN008;
	MOV	ES:[BX.IFSR_RETCLASS],AL						 ;AN008;
	JMP	AA_40				; go process next ifs driver		 ;AN000;
											 ;AN000;
AA_100: 										 ;AN000;
	RestoreReg <DI,ES>			; restore 1st ifs driver		 ;AN000;
AA_120: 										 ;AN000;
	ADD	SI,DX				; ** Next CDS				 ;AN000;
	DEC	CX									 ;AN000;
	JZ	AA_990									 ;AC004;
	JMP	AA_10									 ;AN000;
											 ;AN000;
											 ;AN000;
AA_990: 										 ;AC004;
	RestoreReg <DI,ES,DS>			; restore ds - psp,esdi - storage	 ;AN000;
AA_1000:										 ;AN004;
	AND	CS:IFSPROC_FLAGS,NOT IsInit	; reset isinit				 ;AN010;
	return										 ;AN000;
											 ;AN000;
EndProc AUTO_ATTACH									 ;AN000;
											 ;AN000;
											 ;AN000;
BREAK <CHECK_UNC_PRESENCE -- check if UNC file system driver ifs'ed>                     ;AN000;
											 ;AN000;
;************************************************************************************	 ;AN000;
;											 ;AN000;
; CHECK_UNC_PRESENCE									 ;AN000;
;											 ;AN000;
; Called by: init - general								 ;AN000;
;											 ;AN000;
; Routines called:  SYSDISPMSG								 ;AN000;
;											 ;AN000;
; Inputs:										 ;AN000;
;	None										 ;AN000;
;											 ;AN000;
; Function:										 ;AN000;
;	Get pointer to 1st IFS header							 ;AN000;
;	IF no file systems THEN 							 ;AN000;
;	   Display warning								 ;AN000;
;	ELSE DO 									 ;AN000;
;	       BX=0
;	       WHILE pointer .NOT. 0FFFFH						 ;AN000;
;		  DO									 ;AN000;
;		    OR BX,IFS_ATTRIBUTES
;		    IF file system driver has unc bit set THEN				 ;AN000;
;		       DO								 ;AN000;
;			 Set unc_installed flag in IFSFUNC_FLAGS			 ;AN000;
;			 Set UNC_FS_HDR = unc file system driver header 		 ;AN000;
;			 Set unc_found							 ;AN000;
;		       ENDDO								 ;AN000;
;		  ENDDO 								 ;AN000;
;	       ENDWHILE 								 ;AN000;
;	       IF unc not found THEN							 ;AN000;
;		  Set UNC_FS_HDR = null ptr						 ;AN000;
;	       ENDIF									 ;AN000;
;	       IFS_ATTRS=BX
;	     ENDDO									 ;AN000;
;	ENDIF										 ;AN000;
;											 ;AN000;
; Outputs: unc_installed flag set in ifsfunc_flags in unc present			 ;AN000;
;	   IFS_ATTRS set
;											 ;AN000;
;************************************************************************************	 ;AN000;
											 ;AN000;
	Procedure   CHECK_UNC_PRESENCE,NEAR						 ;AN000;
ASSUME	DS:NOTHING,ES:NOTHING								 ;AN000;
											 ;AN000;
	SaveReg <DS,ES,DI,BX>			; preserve ds - psp,es di storage	 ;AN000;
	MOV	AH,Get_In_Vars			; Get ptr to ifs hdr chain		 ;AN000;
	INT	21h				; es:bx -> sysinitvars			 ;AN000;
	LES	DI,ES:[BX.SYSI_IFS]		; es:di -> 1st ifs driver		 ;AN000;
	XOR	BX,BX									 ;AN000;
	CMP	DI,NULL_PTR			; if 1st null, then no drivers		 ;AN000;
	JNE	CUP_20				; must display no driver msg		 ;AN000;
	MOV	AX,ES									 ;AN000;
	CMP	AX,NULL_PTR								 ;AN000;
	JNE	CUP_20									 ;AN000;
											 ;AN000;
	MOV	AX,UTIL_ERR_4			; def 4  "No IFS drivers found",CR,LF    ;AN000;
	MOV	BX,STDERR								 ;AN000;
	XOR	CX,CX									 ;AN000;
	MOV	DL,NO_INPUT								 ;AN000;
	MOV	DH,UTILITY_MSG_CLASS							 ;AN000;
	PUSH	CS									 ;AN000;
	POP	DS									 ;AN000;
	CALL	SYSDISPMSG								 ;AN000;
	MOV	CS:IFSFUNC_FLAGS,NO_IFS_DRIVERS 					 ;AN000;
											 ;AN000;
	JMP	SHORT CUP_1000								 ;AN000;
											 ;AN000;
CUP_20: 										 ;AN000;
	OR	BX,ES:[DI.IFS_ATTRIBUTE]
	TEST	ES:[DI.IFS_ATTRIBUTE],IFSUNC	; now set UNC_FS_HDR			 ;AN000;
	JNZ	CUP_40									 ;AN000;
CUP_30:
	LES	DI,ES:[DI.IFS_NEXT]							 ;AN000;
	CMP	DI,NULL_PTR								 ;AN000;
	JNE	CUP_20									 ;AN000;
	MOV	AX,ES									 ;AN000;
	CMP	AX,NULL_PTR								 ;AN000;
	JNE	CUP_20									 ;AN000;
	TEST	IFSFUNC_FLAGS,UNC_INSTALLED
	JNZ	CUP_1000
	MOV	WORD PTR [UNC_FS_HDR],NULL_PTR	; no unc - set unc ptr null		 ;AN000;
	MOV	WORD PTR [UNC_FS_HDR+2],NULL_PTR					 ;AN000;
	JMP	SHORT CUP_1000								 ;AN000;
											 ;AN000;
CUP_40: 					; found unc - set unc ptr		 ;AN000;
	MOV	WORD PTR [UNC_FS_HDR],DI	; and unc flag				 ;AN000;
	MOV	WORD PTR [UNC_FS_HDR+2],ES						 ;AN000;
	OR	IFSFUNC_FLAGS,UNC_INSTALLED						 ;AN000;
	JMP	SHORT CUP_30								 ;AN000;
											 ;AN000;
											 ;AN000;
CUP_1000:										 ;AN000;
	RestoreReg <BX,DI,ES,DS>		; restore ds - psp,esdi - storage	 ;AN000;
	return										 ;AN000;

include msgdcl.inc
											 ;AN000;
EndProc CHECK_UNC_PRESENCE								 ;AN000;
											 ;AN000;
											 ;AN000;
IFSSEG	ENDS										 ;AN000;
											 ;AN000;
STACK	SEGMENT STACK									 ;AN000;
DB  278 + 128 DUP (?)		; 278 == IBM's ROM requirements                          ;AN000;
STACK	ENDS										 ;AN000;
											 ;AN000;
END IFSFUNCinit 									 ;AN000;
END											 ;AN000;
