/* * Windows Exec & Help * */ #include #include #include #include #include "neexe.h" #include "segmem.h" #include "prototypes.h" #include "dlls.h" #include "wine.h" #include "windows.h" #include "stddebug.h" /* #define DEBUG_EXEC /* */ /* #undef DEBUG_EXEC /* */ #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 extern struct w_files * wine_files; typedef struct { WORD wEnvSeg; LPSTR lpCmdLine; LPVOID lpCmdShow; DWORD dwReserved; } PARAMBLOCK; typedef BOOL (CALLBACK * LPFNWINMAIN)(HANDLE, HANDLE, LPSTR, int); extern int CallToInit16(unsigned long csip, unsigned long sssp, unsigned short ds); 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 (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); } /********************************************************************** * 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); }