/*
 * Copyright 1995 Martin von Loewis
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include "windows.h"
#include "dlls.h"
#include "pe_image.h"
#include "peexe.h"
#include "relay32.h"
#include "xmalloc.h"
#include "stddebug.h"
#include "debug.h"

WIN32_builtin	*WIN32_builtin_list;

/* Functions are in generated code */
void ADVAPI32_Init();
void COMDLG32_Init();
void GDI32_Init();
void KERNEL32_Init();
void SHELL32_Init();
void USER32_Init();
void WINPROCS32_Init();

int RELAY32_Init(void)
{
#ifndef WINELIB
	/* Add a call for each DLL */
	ADVAPI32_Init();
	COMDLG32_Init();
	GDI32_Init();
	KERNEL32_Init();
	SHELL32_Init();
	USER32_Init();
	WINPROCS32_Init();
#endif
	/* Why should it fail, anyways? */
	return 1;
}

WIN32_builtin *RELAY32_GetBuiltinDLL(char *name)
{
	WIN32_builtin *it;
	size_t len;
	char *cp;

	len = (cp=strchr(name,'.')) ? (cp-name) : strlen(name);
	for(it=WIN32_builtin_list;it;it=it->next)
	if(lstrncmpi(name,it->name,len)==0)
		return it;
	return NULL;
}

void RELAY32_Unimplemented(char *dll, int item)
{
	WIN32_builtin *Dll;
	fprintf( stderr, "No handler for routine %s.%d", dll, item);
	Dll=RELAY32_GetBuiltinDLL(dll);
	if(Dll && Dll->functions[item].name)
		fprintf(stderr, "(%s?)\n", Dll->functions[item].name);
	else
		fprintf(stderr, "\n");
	fflush(stderr);
	exit(1);
}

void *RELAY32_GetEntryPoint(char *dll_name, char *item, int hint)
{
	WIN32_builtin *dll;
	int i;
  	u_short * ordinal;
  	u_long * function;
  	u_char ** name;
	struct PE_Export_Directory * pe_exports;
	unsigned int load_addr;

	dprintf_module(stddeb, "Looking for %s in %s, hint %x\n",
		item ? item: "(no name)", dll_name, hint);
	dll=RELAY32_GetBuiltinDLL(dll_name);
	/* FIXME: This should deal with built-in DLLs only. See pe_module on
	loading PE DLLs */
	if(!dll)
		return 0;
#if 0
	if(!dll) {
		if(!wine_files || !wine_files->name ||
		   lstrcmpi(dll_name, wine_files->name)) {
			LoadModule(dll_name, (LPVOID) -1);
			if(!wine_files || !wine_files->name ||
		   	   lstrcmpi(dll_name, wine_files->name)) 
				return 0;
		}
		load_addr = wine_files->load_addr;
		pe_exports = wine_files->pe->pe_export;
  		ordinal = (u_short *) (((char *) load_addr) + (int) pe_exports->Address_Of_Name_Ordinals);
  		function = (u_long *)  (((char *) load_addr) + (int) pe_exports->AddressOfFunctions);
  		name = (u_char **)  (((char *) load_addr) + (int) pe_exports->AddressOfNames);
		/* import by ordinal */
		if(!item){
			return 0;
		}
		/* hint is correct */
		#if 0
		if(hint && hint<dll->size && 
			dll->functions[hint].name &&
			strcmp(item,dll->functions[hint].name)==0)
			return dll->functions[hint].definition;
		#endif
		/* hint is incorrect, search for name */
		for(i=0;i<pe_exports->Number_Of_Functions;i++)
	            if (name[i] && !strcmp(item,name[i]+load_addr))
	                return function[i]+(char *)load_addr;
	
		/* function at hint has no name (unimplemented) */
		#if 0
		if(hint && hint<dll->size && !dll->functions[hint].name)
		{
			dll->functions[hint].name=xstrdup(item);
			dprintf_module(stddeb, "Returning unimplemented function %s.%d\n",
				dll_name,hint);
			return dll->functions[hint].definition;
		}
		#endif
		printf("Not found\n");
		return 0;
	}
#endif
	/* import by ordinal */
	if(!item){
		if(hint && hint<dll->size)return dll->functions[hint].definition;
		return 0;
	}
	/* hint is correct */
	if(hint && hint<dll->size && 
		dll->functions[hint].name &&
		strcmp(item,dll->functions[hint].name)==0)
		return dll->functions[hint].definition;
	/* hint is incorrect, search for name */
	for(i=0;i<dll->size;i++)
            if (dll->functions[i].name && !strcmp(item,dll->functions[i].name))
                return dll->functions[i].definition;

	/* function at hint has no name (unimplemented) */
	if(hint && hint<dll->size && !dll->functions[hint].name)
	{
		dll->functions[hint].name=xstrdup(item);
		dprintf_module(stddeb, "Returning unimplemented function %s.%d\n",
			dll_name,hint);
		return dll->functions[hint].definition;
	}
	return 0;
}

void RELAY32_DebugEnter(char *dll,char *name)
{
	dprintf_relay(stddeb, "Entering %s.%s\n",dll,name);
}

LONG RELAY32_CallWindowProc( WNDPROC func, int hwnd, int message,
             int wParam, int lParam )
{
	int ret;
__asm__ (
		"push %1;"
		"push %2;"
		"push %3;"
		"push %4;"
		"call %5;"
		: "=a" (ret)
		: "g" (lParam), "g" (wParam), "g" (message), "g" (hwnd), "g" (func)
	);
	return ret;
}
