/*
 * 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 "module.h"
#include "neexe.h"
#include "pe_image.h"
#include "peexe.h"
#include "relay32.h"
#include "struct32.h"
#include "stackframe.h"
#include "xmalloc.h"
#include "ldt.h"
#include "stddebug.h"
#include "debug.h"

#define DLL_ENTRY(name) \
  { #name, (WIN32_function *)name##_Module_Start, \
    (WIN32_function *)name##_Module_End, (int *)name##_Data_Start, NULL }

static WIN32_builtin WIN32_builtin_list[] =
{
    DLL_ENTRY(ADVAPI32),
    DLL_ENTRY(COMCTL32),
    DLL_ENTRY(COMDLG32),
    DLL_ENTRY(OLE32),
    DLL_ENTRY(GDI32),
    DLL_ENTRY(KERNEL32),
    DLL_ENTRY(SHELL32),
    DLL_ENTRY(USER32),
    DLL_ENTRY(WINPROCS32),
    DLL_ENTRY(WINSPOOL)
};

#define NB_DLLS (sizeof(WIN32_builtin_list)/sizeof(WIN32_builtin_list[0]))

static void RELAY32_MakeFakeModule(WIN32_builtin*dll);

int RELAY32_Init(void)
{
    int i;

    for (i = 0; i < NB_DLLS; i++)
        RELAY32_MakeFakeModule( &WIN32_builtin_list[i] );

    /* Why should it fail, anyways? */
    return 1;
}

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

	len = (cp=strchr(name,'.')) ? (cp-name) : strlen(name);
	for(i = NB_DLLS, it = WIN32_builtin_list; (i > 0); i--, it++)
            if (!lstrncmpi(name,it->name,len)) 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(WIN32_builtin *dll, char *item, int hint)
{
	int i, size;

	dprintf_module(stddeb, "Looking for %s in %s, hint %x\n",
		item ? item: "(no name)", dll->name, hint);
	if(!dll)
		return 0;
        size = (int)(dll->last_func - dll->functions);

	/* import by ordinal */
	if(!item){
		if(hint && hint < size)
			return dll->functions[hint - *dll->base].definition;
		return 0;
	}
	/* hint is correct */
	if(hint && hint < 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 < 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 < 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;
}

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;
}

LONG RELAY32_CallWindowProcConvStruct( WNDPROC func, int hwnd, int message,
	int wParam, LPARAM lParam16)
{
	WINDOWPOS32 wp;
	union {
		MINMAXINFO32 mmi;
		NCCALCSIZE_PARAMS32 nccs;
		CREATESTRUCT32 cs;
	} st;
	CREATESTRUCT *lpcs;
	LONG result;
	void *lParam;
	if(!lParam16)
		return RELAY32_CallWindowProc(func,hwnd,message,wParam,(int)lParam16);
	lParam = PTR_SEG_TO_LIN(lParam16);
	switch(message) {
		case WM_GETMINMAXINFO:
			STRUCT32_MINMAXINFO16to32(lParam,&st.mmi);
			result=RELAY32_CallWindowProc(func,hwnd,message,wParam,(int)&st.mmi);
			STRUCT32_MINMAXINFO32to16(&st.mmi,lParam);
			return result;
		case WM_WINDOWPOSCHANGING:
		case WM_WINDOWPOSCHANGED:
			STRUCT32_WINDOWPOS16to32(lParam,&wp);
			result=RELAY32_CallWindowProc(func,hwnd,message,wParam,(int)&wp);
			STRUCT32_WINDOWPOS32to16(&wp,lParam);
			return result;
		case WM_NCCALCSIZE:
			STRUCT32_NCCALCSIZE16to32Flat(lParam,&st.nccs);
			if(((NCCALCSIZE_PARAMS*)lParam)->lppos) {
				STRUCT32_WINDOWPOS16to32(((NCCALCSIZE_PARAMS*)lParam)->lppos,&wp);
				st.nccs.lppos=&wp;
			} else
				st.nccs.lppos= 0;
			result=RELAY32_CallWindowProc(func,hwnd,message,wParam,(int)&st.nccs);
			STRUCT32_NCCALCSIZE32to16Flat(&st.nccs,lParam);
			if(((NCCALCSIZE_PARAMS*)lParam)->lppos)
				STRUCT32_WINDOWPOS32to16(&wp,((NCCALCSIZE_PARAMS*)lParam)->lppos);
			return result;
		case WM_NCCREATE:
			lpcs = (CREATESTRUCT*)lParam;
			STRUCT32_CREATESTRUCT16to32(lParam,&st.cs);
			st.cs.lpszName = HIWORD(lpcs->lpszName) ? 
				PTR_SEG_TO_LIN(lpcs->lpszName) : (char*)lpcs->lpszName;
			st.cs.lpszClass = HIWORD(lpcs->lpszClass) ? 
				PTR_SEG_TO_LIN(lpcs->lpszClass) : (char*)lpcs->lpszClass;
			result=RELAY32_CallWindowProc(func,hwnd,message,wParam,(int)&st.cs);
			STRUCT32_CREATESTRUCT32to16(&st.cs,lParam);
			lpcs->lpszName = HIWORD(st.cs.lpszName) ? 
				MAKE_SEGPTR(st.cs.lpszName) : (SEGPTR)st.cs.lpszName;
			lpcs->lpszClass = HIWORD(st.cs.lpszClass) ? 
				MAKE_SEGPTR(st.cs.lpszClass) : (SEGPTR)st.cs.lpszClass;
			return result;
		case WM_GETTEXT:
		case WM_SETTEXT:
			return RELAY32_CallWindowProc(func,hwnd,message,wParam,(int)lParam);
		default:
			fprintf(stderr,"No conversion function for message %d\n",message);
	}
	return RELAY32_CallWindowProc(func,hwnd,message,wParam,(int)lParam);
}

static void RELAY32_MakeFakeModule(WIN32_builtin*dll)
{
	NE_MODULE *pModule;
	struct w_files *wpnt;
	int size;
	HMODULE hModule;
	OFSTRUCT *pFileInfo;
	char *pStr;
	wpnt=xmalloc(sizeof(struct w_files));
	wpnt->hinstance=0;
	wpnt->hModule=0;
	wpnt->initialised=1;
	wpnt->mz_header=wpnt->pe=0;
	size=sizeof(NE_MODULE) +
		/* loaded file info */
		sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName) +
                strlen(dll->name) + 1 +
		/* name table */
		12 +
		/* several empty tables */
		8;
	hModule = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, size );
	wpnt->hModule = hModule;
	FarSetOwner( hModule, hModule );
	pModule = (NE_MODULE*)GlobalLock(hModule);
	/* Set all used entries */
	pModule->magic=NE_SIGNATURE;
	pModule->count=1;
	pModule->next=0;
	pModule->flags=NE_FFLAGS_WIN32;
	pModule->dgroup=0;
	pModule->ss=0;
	pModule->cs=0;
	pModule->heap_size=0;
	pModule->stack_size=0;
	pModule->seg_count=0;
	pModule->modref_count=0;
	pModule->nrname_size=0;
	pModule->seg_table=0;
	pModule->fileinfo=sizeof(NE_MODULE);
	pModule->os_flags=NE_OSFLAGS_WINDOWS;
	pModule->expected_version=0x30A;
	pFileInfo=(OFSTRUCT *)(pModule + 1);
	pFileInfo->cBytes = sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName)
                            + strlen(dll->name);
	strcpy( pFileInfo->szPathName, dll->name );
	pStr = ((char*)pFileInfo) + pFileInfo->cBytes + 1;
	pModule->name_table=(int)pStr-(int)pModule;
	*pStr=strlen(dll->name);
	strcpy(pStr+1,dll->name);
	pStr += *pStr+1;
	pModule->res_table=pModule->import_table=pModule->entry_table=
		(int)pStr-(int)pModule;
	MODULE_RegisterModule(hModule);
	wpnt->builtin=dll;
	wpnt->next=wine_files;
	wine_files=wpnt;
}



