blob: 771fba294c19ce6bf5ceb7a34d989a3303f46d2b [file] [log] [blame]
/*
* 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);
}