	TITLE	LDFILE - Loader file I/O procedures

.xlist
include kernel.inc
include newexe.inc
.list

externFP GlobalAlloc
externFP GlobalFree
externFP MyOpenFile
externFP Int21Handler

sBegin	CODE
assumes CS,CODE

externNP MyLock

;-----------------------------------------------------------------------;
; LoadNRTable								;
; 									;
; Returns the segment address of the non-resident name table.		;
; 									;
; Arguments:								;
;	parmW	hexe		exeheader to load NRTable from		;
;	parmW	fh		file handle, -1 if none 		;
;	parmD	oNRTable	if batching, this is where we left off	;
;	parmD	lpNRbuffer	if batching, this is buffer to use	;
;	parmW	cbNRbuffer	if batching, this is size of buffer	;
; 									;
; Returns:								;
;	DX:AX = pointer to non-resident table				;
;	CX:BX = if batching this is where to pick up from		;
;									;
; Error Returns:							;
;	DX:AX = NULL							;
;									;
; Registers Preserved:							;
; 									;
; Registers Destroyed:							;
; 									;
; Calls:								;
;	MyOpenFile							;
;	GlobalAlloc							;
;	MyLock								;
; 									;
; History:								;
; 									;
;  Tue 09-May-1989 18:38:04  -by-  David N. Weise  [davidw]		;
; Added the batching if out of memory.					;
;									;
;  Thu Oct 08, 1987 10:11:42p  -by-  David N. Weise   [davidw]		;
; Added this nifty comment block and fixed it for fastboot.		;
;-----------------------------------------------------------------------;

cProc	LoadNRTable,<PUBLIC,NEAR>,<si,di>
	parmW	hexe
	parmW	fh
	parmD	oNRTable
	parmD	lpNRbuffer
	parmW	cbNRbuffer

	localD	lt_ExeoNRTable		; the real offset in the Exe
	localD	lt_oNRTable
	localB	fBatching
	localB	fFirstTime
	localW	cbnrestab
	localW	pfileinfo		; used for debugging only
cBegin
	mov	cx,oNRTable.hi		; Are we batching?
	or	cx,oNRTable.lo
	or	cl,ch
	mov	fBatching,cl
	xor	di,di
	mov	fFirstTime,0

if KDEBUG
	mov	pfileinfo,di
endif
	mov	es,hexe
	mov	si,ne_nrestab
	mov	bx,fh
	mov	dx,es:[si][2]		; Get potential segment address
	mov	ax,es:[si][0]
	inc	bx			; Were we passed a file handle
	jnz	ltopen			; Yes, go read then
	mov	dx,es:[di].ne_pfileinfo ; No, then open the file
if SHARE_AWARE
	mov	bx,OF_REOPEN or OF_PROMPT or OF_CANCEL or OF_VERIFY or OF_NO_INHERIT or OF_SHARE_DENY_WRITE
else
	mov	bx,OF_REOPEN or OF_PROMPT or OF_CANCEL or OF_VERIFY or OF_NO_INHERIT
endif
if KDEBUG
	mov	pfileinfo,dx
	krDebugOut <DEB_TRACE or DEB_krLoadSeg>, "Non-Res name table of @ES:DX"
endif
	regptr	esdx,es,dx
	push	dx
	push	es
	cCall	MyOpenFile,<esdx,esdx,bx>
	pop	es
	pop	dx
;;;	cmp	ax, -1
;;;	jne	@F
;;;
;;;	mov	bx,OF_REOPEN or OF_VERIFY or OF_NO_INHERIT
;;;	cCall	MyOpenFile,<esdx,esdx,bx>		   
;;;
;;;@@:
	mov	es,hexe
	inc	bx
	jnz	ltopen
	jmp	ltfail
ltopen:
	krDebugOut <DEB_TRACE or DEB_krLoadSeg>, "Loading %es2 Nonresident name table"
	dec	bx
	mov	dx,es:[si][0]		; AX:DX = file address of table
	mov	ax,es:[si][2]
	cmp	es:[di].ne_pfileinfo,di ; Is the NRTable in WIN200.OVL?
	jnz	lt_seek
	mov	cx,4			; Shift left AX:DX by 4.
lt_winovl:
	shl	dx,1
	rcl	ax,1
	loop	lt_winovl
lt_seek:
	mov	lt_ExeoNRTable.hi,ax
	mov	lt_ExeoNRTable.lo,dx
	cmp	fBatching,0		; Are we batching?
	jz	lt_not_batching
	mov	ax,oNRTable.hi
	mov	dx,oNRTable.lo
lt_not_batching:
	mov	lt_oNRTable.hi,ax
	mov	lt_oNRTable.lo,dx
	mov	cx,ax			; CX:DX = file address of table
	mov	ax,4200h		; Seek to beginning of the table
	DOSCALL
	jnc	@F
	jmp	ltfail
@@:	push	es
	push	bx
	cmp	fBatching,0
	jz	lt_first_time
lt_got_no_space:
	mov	es,hexe
	mov	dx,oNRTable.hi
	mov	ax,oNRTable.lo
	sub	ax,lt_ExeoNRTable.lo	; compute the bytes read so far
	sbb	dx,lt_ExeoNRTable.hi
	sub	ax,es:[di].ne_cbnrestab
	neg	ax
	cmp	ax,cbNRbuffer
	jbe	@F
	mov	ax,cbNRbuffer
@@:	mov	cbnrestab,ax

	les	di,lpNRbuffer
	mov	ax,es
	mov	dx,ax
	jmps	lt_share_your_space

lt_first_time:
	mov	fFirstTime,1		; make non-zero
	mov	ax,es:[ne_cbnrestab]	; first time through
	mov	cbnrestab,ax
	add	ax,4
	mov	bx,GA_MOVEABLE or GA_NODISCARD
	xor	cx,cx

	cCall	 GlobalAlloc,<bx,cx,ax>
	xor	dx,dx
	or	ax,ax
	jnz	lt_got_space

	mov	ax,lt_oNRTable.hi
	mov	oNRTable.hi,ax
	mov	ax,lt_oNRTable.lo
	mov	oNRTable.lo,ax
	mov	fBatching,1
	jmp	lt_got_no_space

lt_got_space:
	cCall	MyLock,<ax>
	xor	di,di
lt_share_your_space:
	pop	bx
	mov	cx,ds			; Save DS
	pop	ds
	push	cx			; after alloc
	mov	es,ax
	cmp	fBatching,0
	jnz	@F
	xor	ax,ax			; Set table loaded indicator
	xchg	ds:[si],ax
	cld
	stosw				; Save file offset
	mov	ax,dx
	xchg	ds:[si+2],ax		; Set segment handle
	stosw				; Save file offset
@@:	mov	cx,cbnrestab
	smov	ds,es
	push	dx
	mov	dx,di
	mov	ah,3Fh			; Read in the table
	DOSCALL
	pop	dx
	pop	ds
	jc	ltfail			; did the DOS call fail?
	cmp	ax,cx			; did we get all the bytes?
	jne	ltfail

	cmp	fBatching,0		; are we batching?
	jz	ltdone
	std				; truncate to whole strings
	push	bx
	xor	ax,ax
	xor	bx,bx
	mov	dx,cbNRbuffer
	dec	dx
@@:	cmp	byte ptr es:[di][bx],0	; are we at end of NRTable?
	jnz	lt_not_buffer_end
	xor	ax,ax
	mov	oNRTable.hi,ax
	mov	oNRTable.lo,ax
	jmps	lt_return_buffer
lt_not_buffer_end:
	mov	cx,bx
	mov	al,byte ptr es:[di][bx]
	add	bx,ax
	add	bx,3
	cmp	bx,dx
	jb	@B
	mov	bx,cx
	mov	byte ptr es:[di][bx],0
	add	oNRTable.lo,bx
	adc	oNRTable.hi,0
lt_return_buffer:
	pop	bx
	les	ax,lpNRbuffer
	mov	dx,es
	cmp	fFirstTime,0
	jnz	ltdone_0
	jmps	ltexit

ltdone:
	push	bx
	cCall	MyLock,<dx>
	pop	bx
	mov	dx,ax
	mov	ax,4
ltdone_0:
	mov	es,dx
	mov	si,ax
	xor	ax,ax
	mov	al,es:[si]
	add	ax,si
	add	ax,3
	jmps	ltexit
ltfail:
if KDEBUG
	push	bx
	kerror	ERR_LDNRTABLE,<Unable to load non-resident name table from >,hexe,pfileinfo
;;;	kerror	ERR_LDNRTABLE,<(TRY FILES=30 to fix this) Unable to load non-resident name table from >,hexe,pfileinfo
	pop	bx
endif
	xor	ax,ax
	xor	dx,dx

ltexit: cmp	bx,fh
	je	ltx1
	push	ax
	mov	ah,3Eh
	DOSCALL
	pop	ax
ltx1:
	mov	cx,oNRTable.hi
	mov	bx,oNRTable.lo
	cld				; we'll be polite
cEnd


;
; GetStringPtr( hExe, offset ) - Procedure to return the far address of a
; string in the passed new EXE file's string table
;
cProc	GetStringPtr,<PUBLIC,NEAR>,<si,di>
	parmW	hExe
	parmW	fh
	parmW	soffset
cBegin
	mov	es,hExe
	mov	dx,es
	mov	ax,es:[ne_imptab]
	add	ax,soffset
cEnd


; FreeNRTable( lptable ) - Procedure to free table allocated by LoadNRTable
; and restore the new EXE header information.

cProc	FreeNRTable,<PUBLIC,FAR>,<si,di>
	parmW	hexe
	parmW	tblid
cBegin
	mov	es,hexe
	mov	di,tblid
	xor	ax,ax
	mov	cx,es:[di+2]
	cmp	word ptr es:[di],0
	jne	lfexit
	jcxz	lfexit
	push	cx
	cCall	MyLock,<cx>
	pop	cx
	mov	es,hexe
	push	ds
	mov	ds,ax
	xor	si,si
	cld
	movsw
	movsw
	pop	ds
	cCall	GlobalFree,<cx>
lfexit:
cEnd

sEnd	CODE

end
