Wed Dec 7 14:52:25 1994 Alexandre Julliard (julliard@lamisun.epfl.ch) * [controls/listbox.c] Fixed problems due to new scroll-bar code. * [loader/signal.c] [miscemu/ioports.c] Handle I/O opcodes that use an absolute address. * [objects/text.c] Implemented TabbedTextOut(). Sat Dec 3 18:53:08 1994 Kenneth MacDonald <K.MacDonald@ed.ac.uk> * [objects/metafile.c] Implemented GetMetafile(). Fixed bug in PlayMetaFile() when reading disc based metafile records. Added META_POLYPOLYGON, META_DELETEOBJECT and META_EOF to PlayMetaFileRecord(). Wed Nov 30 06:32:25 1994 Martin von Loewis (martin@cs.csufresno.edu) * [Imakefile] wine.sym: Remove gcc2_compiled and friends * [controls/listbox.c][if1632/relay.c][if1632/relay.c] [loader/resource.c][memory/heap.c][objects/dib.c][windows/dialog.c] Replace #ifdef DEBUG_XXX with if(debugging_xxx){ * [if1632/call.S] CallToLibMain: New function * [if1632/relay.c][include/options.h][misc/main.c] [miscemu/int1a.c][miscemu/int21.c][miscemu/kernel.c] removed Options.relay_debug * [include/heap.h] HEAP_OWNER: Use ds instead of cs:ip * [loader/ne_image.c] LoadNEImage: Remember current exe, handle nodata dlls InitNEDLL: handle nodata dlls, call CallToLibMain * [loader/selector.c] CreateSelectors: Initialize auto_data_sel with 0 * [memory/heap.c] HEAP_CheckHeap: Check prev HEAP_CheckLocalHeaps: new function * [misc/profile] Remember and dump only changed profiles * [tools/makedebug] Introduce debugging_xxx flags Sun Nov 27 23:13:22 MET 1994 <erik@xs4all.nl> * [clipboard.h color.h dc.h dos_fs.h event.h font.h graphics.h if1632.h kernel.h library.h miscemu.h ne_image.h nonclient.h pe_image.h selectors.h wintypes.h] Added. * [*/*] - Commented all 'static char copyright statements', see misc/main.c - moved prototypes to headers files, fixed wrong prototypes. - *please* add a header file for each .c if you need to export things. * [misc/main.c] Added one static string which list the names of the contributors. Fri Nov 25 16:24:27 MET 1994 Dag Asheim (dash@ifi.uio.no) * [Configure] Made the support for multiple languages more automatic. Added a [fonts] section to the wine.conf file. Made the defaults better. Generally cleaned it up. * [rc/sysres_No.rc] [rc/sysres_De.rc] [rc/sysres.c] Norwegian resources and small fixes to the german resources. Wed Nov 23 20:28:59 1994 Martin von Loewis (martin@cs.csufresno.edu) * [debugger/break.c] bark(), toggle_next(), should_continue(): New functions insert_break(): Fixed, adds write access to page before writing wine_bp.next_addr: new structure field * [debugger/dbg.y] Changed symbol's value to be it's value instead of the value pointed to by the symbol. Changed SIGTRAP handling to allow continuation after break point * [misc/shell.c] ShellAbout(): Load resource from memory
256 lines
6.8 KiB
C
256 lines
6.8 KiB
C
/*
|
|
* Windows Exec & Help
|
|
*
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include "neexe.h"
|
|
#include "segmem.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].selector;
|
|
cs_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->cs-1].selector;
|
|
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(cs_reg << 16 | ip_reg, ds_reg);
|
|
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].selector);
|
|
cs_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->cs-1].selector;
|
|
ip_reg = wpnt->ne->ne_header->ip;
|
|
ss_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->ss-1].selector;
|
|
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);
|
|
}
|