/*
*     Windows Exec & Help
*
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "neexe.h"
#include "prototypes.h"
#include "dlls.h"
#include "windows.h"
#include "if1632.h"
#include "callback.h"
#include "library.h"
#include "ne_image.h"
#include "stddebug.h"
#include "debug.h"

#define HELP_CONTEXT      0x0001
#define HELP_QUIT         0x0002
#define HELP_INDEX        0x0003
#define HELP_CONTENTS     0x0003
#define HELP_HELPONHELP   0x0004
#define HELP_SETINDEX     0x0005
#define HELP_SETCONTENTS  0x0005
#define HELP_CONTEXTPOPUP 0x0008
#define HELP_FORCEFILE    0x0009
#define HELP_KEY          0x0101
#define HELP_COMMAND      0x0102
#define HELP_PARTIALKEY   0x0105
#define HELP_MULTIKEY     0x0201
#define HELP_SETWINPOS    0x0203

typedef struct {
	WORD	wEnvSeg;
	LPSTR	lpCmdLine;
	LPVOID	lpCmdShow;
	DWORD	dwReserved;
	} PARAMBLOCK;

typedef BOOL (CALLBACK * LPFNWINMAIN)(HANDLE, HANDLE, LPSTR, int);

HANDLE CreateNewTask(HINSTANCE hInst);

#ifndef WINELIB
void InitializeLoadedNewDLLs(HINSTANCE hInst)
{
    struct w_files * w;
    struct w_files * wpnt;
    int cs_reg, ds_reg, ip_reg;
    int rv;

    dprintf_exec(stddeb, "Initializing New DLLs\n");

    /*
     * Initialize libraries
     */
    dprintf_exec(stddeb,
	"InitializeLoadedNewDLLs() before searching hInst=%04X !\n", hInst);
	w = wine_files;
	while (w && w->hinstance != hInst) w = w->next;
	if (w == NULL) return;
    dprintf_exec(stddeb,"InitializeLoadedNewDLLs() // before InitLoop !\n");
    for(wpnt = w; wpnt; wpnt = wpnt->next)
    {
	/* 
	 * Is this a library? 
	 */
	if (wpnt->ne->ne_header->format_flags & 0x8000)
	{
	    if (!(wpnt->ne->ne_header->format_flags & 0x0001))
	    {
		/* Not SINGLEDATA */
		fprintf(stderr, "Library is not marked SINGLEDATA\n");
		exit(1);
	    }

	    ds_reg = wpnt->ne->selector_table[wpnt->ne->
					  ne_header->auto_data_seg-1];
	    cs_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->cs-1];
	    ip_reg = wpnt->ne->ne_header->ip;

        dprintf_exec(stddeb, "Initializing %s, cs:ip %04x:%04x, ds %04x\n",
		    wpnt->name, cs_reg, ip_reg, ds_reg);

            rv = CallTo16_regs_( (FARPROC)(cs_reg << 16 | ip_reg), ds_reg,
                                 0 /*es*/, 0 /*ax*/, 0 /*bx*/, 0 /*cx*/,
                                 0 /*dx*/, 0 /*si*/, wpnt->hinstance /*di*/ );
        dprintf_exec(stddeb,"rv = %x\n", rv);
	}
    }
}


void StartNewTask(HINSTANCE hInst)
{
	struct w_files * wpnt;
	struct w_files * w;
	int cs_reg, ds_reg, ss_reg, ip_reg, sp_reg;
	int rv;
	int segment;

    	dprintf_exec(stddeb,
		"StartNewTask() before searching hInst=%04X !\n", hInst);
	wpnt = wine_files;
	while (wpnt && wpnt->hinstance != hInst) wpnt = wpnt->next;
	if (wpnt == NULL) return;
    	dprintf_exec(stddeb,"StartNewTask() // before FixupSegment !\n");
	for(w = wpnt; w; w = w->next)	{
		for (segment = 0; segment < w->ne->ne_header->n_segment_tab; segment++) {
			if (NE_FixupSegment(w, segment) < 0) {
				myerror("fixup failed.");
				}
			}
		}
	dprintf_exec(stddeb,"StartNewTask() before InitializeLoadedNewDLLs !\n");
	InitializeLoadedNewDLLs(hInst);
	dprintf_exec(stddeb,"StartNewTask() before setup register !\n");
    ds_reg = (wpnt->ne->selector_table[wpnt->ne->ne_header->auto_data_seg-1]);
    cs_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->cs-1];
    ip_reg = wpnt->ne->ne_header->ip;
    ss_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->ss-1];
    sp_reg = wpnt->ne->ne_header->sp;

	dprintf_exec(stddeb,"StartNewTask() before CallToInit16() !\n");
/*
    rv = CallToInit16(cs_reg << 16 | ip_reg, ss_reg << 16 | sp_reg, ds_reg);
*/
    dprintf_exec(stddeb,"rv = %x\n", rv);

}

#else
void StartNewTask (HINSTANCE hInst)
{
    fprintf(stdnimp, "StartNewTask(): Not yet implemented\n");
}
#endif

/**********************************************************************
 *				LoadModule	[KERNEL.45]
 */
HANDLE LoadModule(LPSTR modulefile, LPVOID lpParamBlk)
{
	PARAMBLOCK  *pblk = lpParamBlk;
	WORD 	*lpCmdShow;
    	dprintf_exec(stddeb,"LoadModule '%s' %p\n", modulefile, lpParamBlk);
	if (lpParamBlk == NULL) return 0;
	lpCmdShow = (WORD *)pblk->lpCmdShow;
	return WinExec(pblk->lpCmdLine, lpCmdShow[1]);
}


/**********************************************************************
 *				WinExec		[KERNEL.166]
 */
WORD WinExec(LPSTR lpCmdLine, WORD nCmdShow)
{
	int 		c = 0;
	int 		x, x2;
	char 		*ArgV[20];
	HINSTANCE	hInst = 0;
	HANDLE		hTask = 0;
    	dprintf_exec(stddeb,"WinExec('%s', %04X)\n", lpCmdLine, nCmdShow);
/*	ArgV[0] = "wine";
	c = 1; */
	for (x = x2 = 0; x < strlen(lpCmdLine) + 1; x++) {
		if ((lpCmdLine[x] == ' ') || (lpCmdLine[x] == '\0')) {
			ArgV[c] = (char *)malloc(x - x2 + 1);
			strncpy(ArgV[c], &lpCmdLine[x2], x - x2);
			ArgV[c][x - x2] = '\0';
			c++;   x2 = x + 1;
			}							  
		}  
	ArgV[c] = NULL;
    for (c = 0; ArgV[c] != NULL; c++) 
	dprintf_exec(stddeb,"--> '%s' \n", ArgV[c]);
	switch(fork()) {
		case -1:
            fprintf(stderr,"Can't 'fork' process !\n");
			break;
		case 0:
			if ((hInst = LoadImage(ArgV[0], EXE, 1)) == (HINSTANCE) NULL ) {
				fprintf(stderr, "wine: can't find %s!.\n", ArgV[0]);
                		fprintf(stderr,"Child process died !\n");
				exit(1);
				}
			hTask = CreateNewTask(hInst);
            		dprintf_exec(stddeb,
			"WinExec // hTask=%04X hInst=%04X !\n", hTask, hInst);
			StartNewTask(hInst); 
/*
			lpfnMain = (LPFNWINMAIN)GetProcAddress(hInst, (LPSTR)0L);
            		dprintf_exec(stddeb,
			"WineExec() // lpfnMain=%08X\n", (LONG)lpfnMain);
			if (lpfnMain != NULL) {
				(lpfnMain)(hInst, 0, lpCmdLine, nCmdShow);
                		dprintf_exec(stddeb,
					"WineExec() // after lpfnMain\n");
				}
*/
/*			hTask = CreateNewTask(0);
            		dprintf_exec(stddeb,
				"WinExec // New Task hTask=%04X !\n", hTask);
			execvp(ArgV[0], ArgV); */

            		fprintf(stderr,"Child process died !\n");
			exit(1);
		default:
            		dprintf_exec(stddeb,
			"WinExec (Main process stay alive) hTask=%04X !\n", 
			hTask);
			break;         
		}
	for (c = 0; ArgV[c] != NULL; c++) 	free(ArgV[c]);
	return hTask;
}


/**********************************************************************
 *				ExitWindows		[USER.7]
 */
BOOL ExitWindows(DWORD dwReserved, WORD wRetCode)
{
    dprintf_exec(stdnimp,"EMPTY STUB !!! ExitWindows(%08lX, %04X) !\n", 
		dwReserved, wRetCode);

   exit(wRetCode);
}


/**********************************************************************
 *				WinHelp		[USER.171]
 */
BOOL WinHelp(HWND hWnd, LPSTR lpHelpFile, WORD wCommand, DWORD dwData)
{
	char	str[256];
    	dprintf_exec(stddeb,"WinHelp(%s, %u, %lu)\n", 
		lpHelpFile, wCommand, dwData);
	switch(wCommand) {
	case 0:
	case HELP_HELPONHELP:
		GetWindowsDirectory(str, sizeof(str));
		strcat(str, "\\winhelp.exe");
        dprintf_exec(stddeb,"'%s'\n", str);
		break;
	case HELP_INDEX:
		GetWindowsDirectory(str, sizeof(str));
		strcat(str, "\\winhelp.exe");
        dprintf_exec(stddeb,"'%s'\n", str);
		break;
	default:
		return FALSE;
	}
	WinExec(str, SW_SHOWNORMAL);
	return(TRUE);
}
