	.386p


	include cw.inc


	extrn __CWAPI_FINDMODULE:far
	extrn __CWAPI_FINDFUNCTION:far
	extrn __CWAPI_UNFINDMODULE:far


	.code


;****************************************************************************
;Load a module by file name. If the module already exists in memory a new
;version will still be loaded.
;
;Usage: LoadLibrary(file_name);
;
;Returns:
;
;EAX	zero on error else module handle.
;
;file_name is a standard zero terminated string.
;
;Handles returned by this function should always be released via FreeLibrary()
;
;****************************************************************************
_LoadLibrary	proc	near
	public _LoadLibrary
	pushad
;
;Let cwLoad have a go at loading it.
;
	mov	edx,[esp+(4*8)+4]
	sys	cwLoad
	jnc	@@4
	xor	edx,edx
	jmp	@@5
;
;Store entry/exit address in EPSP.
;
@@4:	push	es
	mov	es,si
	mov	edi,offset EPSP_EntryCSEIP
	mov	es:dword ptr [edi],edx
	mov	es:word ptr [edi+4],cx
	pop	es
;
;Get PSP linear address.
;
	mov	bx,si
	sys	GetSelDet32
;
;Call entry code.
;
	push	ds
	push	es
	push	fs
	push	gs
	pushad
	push	ebx
	pop	fs
	mov	ds,bx
	mov	es,bx
	xor	eax,eax
	mov	ax,es:word ptr[edi+4]
	lar	eax,eax
	test	eax,00400000h
	mov	eax,0
	jnz	@@6
	db 66h
@@6:	call	fs:fword ptr[edi]
	or	ax,ax
	popad
	pop	gs
	pop	fs
	pop	ds
	pop	es
	jz	@@5
;
;Initialisation failed so release this PSP.
;
	mov	bx,si
	sys	RelMem
	xor	edx,edx
;
;Return handle (or error) to caller.
;
@@5:	mov	[esp+(4*8)+4],edx	;Use calling parameter space.
	popad
	mov	eax,[esp+4]		;Get return value.
	ret
_LoadLibrary	endp


;****************************************************************************
;Releases a LoadLibrary module handle back to the system.
;
;Usage: FreeLibrary(module_handle);
;
;Returns:
;
;nothing.
;
;module_handle is the value returned by LoadLibrary();
;
;****************************************************************************
_FreeLibrary	proc	near
	public _FreeLibrary
	pushad
;
;Call terminate code.
;
	mov	edx,[esp+(4*8)+4]
	xor	ebx,ebx
	mov	bx,EPSP_PSPSel[edx]
	push	ds
	push	es
	push	fs
	push	gs
	pushad
	push	ebx
	pop	fs
	mov	ds,bx
	mov	es,bx
	xor	eax,eax
	mov	edi,offset EPSP_EntryCSEIP
	mov	ax,es:word ptr[edi+4]
	lar	eax,eax
	test	eax,00400000h
	mov	eax,1
	jnz	@@7
	db 66h
@@7:	call	fs:fword ptr[edi]
	popad
	pop	gs
	pop	fs
	pop	ds
	pop	es
;
;Release the module.
;
	mov	bx,EPSP_PSPSel[edx]
	sys	RelSel
;
	popad
	ret
_FreeLibrary	endp


;****************************************************************************
;Load a module by module name. If the module is already in memory then just
;return the handle for the existing copy.
;
;Usage: LoadModule(module_name);
;
;Returns:
;
;EAX 	zero on error else module handle.
;
;module_name is a standard zero terminated string.
;
;Handles returned by this function should always be released via FreeModule()
;
;****************************************************************************
_LoadModule	proc	near
	public _LoadModule
	pushad
;
;Build the module name string in the format CauseWay API likes.
;
	mov	esi,[esp+(4*8)+4]	;Point to module name
	mov	edi,esi
	or	ecx,-1
	xor	al,al
	cld
	repnz	scasb		;get the strings length.
	not	ecx
	dec	ecx		;Don't include terminator.
	mov	edi,offset NameSpace
	mov	[edi],cl
	inc	edi
	rep	movsb
;
;Call API code.
;
	mov	esi,offset NameSpace
	call	__CWAPI_FindModule
	jnc	@@0
	xor	edi,edi		;Zero the handle
;
;Return handle (or error) to caller.
;
@@0:	mov	[esp+(4*8)+4],edi	;Use calling parameter space.
	popad
	mov	eax,[esp+4]		;Get return value.
	ret
_LoadModule	endp


;****************************************************************************
;Releases a LoadModule() module handle back to the system.
;
;Usage: FreeModule(module_handle);
;
;Returns:
;
;nothing.
;
;module_handle is the value returned by LoadModule();
;
;****************************************************************************
_FreeModule	proc	near
	public _FreeModule
	pushad
;
;Call API code.
;
	mov	edi,[esp+(4*8)+4]
	call	__CWAPI_UnFindModule
;
	popad
	ret
_FreeModule	endp


;****************************************************************************
;Returns the address of a symbol in a module.
;
;Usage: GetProcAddress(module_handle,function_name);
;
;Returns:
;
;zero on error else function address. (EDX:EAX, use just EAX for FLAT)
;
;module_handle is the value returned by LoadModule() or LoadLibrary()
;module_name is a standard zero terminated string.
;
;****************************************************************************
_GetProcAddress proc near
	public _GetProcAddress
	pushad
;
;Build the function name string in the format CauseWay API likes.
;
	mov	esi,[esp+(4*8)+4+4]
	mov	edi,esi
	or	ecx,-1
	xor	al,al
	cld
	repnz	scasb		;get the strings length.
	not	ecx
	dec	ecx		;Don't include terminator.
	mov	edi,offset NameSpace
	mov	[edi],cl
	inc	edi
	rep	movsb
;
;Call API code.
;
	mov	ebp,offset NameSpace
	mov	edi,[esp+(4*8)+4]
	mov	edi,EPSP_Exports[edi]
	call	__CWAPI_FindFunction
	jnc	@@2
	xor	ecx,ecx		;Zero the address
	xor	edx,edx
	jmp	@@3
;
;Fetch function address.
;
@@2:	mov	edx,[edi]
	xor	ecx,ecx
	mov	cx,[edi+4]
;
;Return function (or error) to caller.
;
@@3:	mov	[esp+(4*8)+4],edx	;Use calling parameter space.
	mov	[esp+(4*8)+4+4],ecx
	popad
	mov	eax,[esp+4]		;Get return value.
	mov	edx,[esp+4+4]
	ret
_GetProcAddress endp


	.data


NameSpace	db 257 dup (0)


	end

