Release 960805
[wine] / misc / exec.c
1 /*
2 *     Windows Exec & Help
3 *
4 */
5
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include "windows.h"
11 #include "heap.h"
12 #include "neexe.h"
13 #include "shell.h"
14 #include "stddebug.h"
15 #include "debug.h"
16 #include "win.h"
17
18 #define HELP_CONTEXT      0x0001
19 #define HELP_QUIT         0x0002
20 #define HELP_INDEX        0x0003
21 #define HELP_CONTENTS     0x0003
22 #define HELP_HELPONHELP   0x0004
23 #define HELP_SETINDEX     0x0005
24 #define HELP_SETCONTENTS  0x0005
25 #define HELP_CONTEXTPOPUP 0x0008
26 #define HELP_FORCEFILE    0x0009
27 #define HELP_KEY          0x0101
28 #define HELP_COMMAND      0x0102
29 #define HELP_PARTIALKEY   0x0105
30 #define HELP_MULTIKEY     0x0201
31 #define HELP_SETWINPOS    0x0203
32
33
34 /***********************************************************************
35  *           EXEC_ExitWindows
36  *
37  * Clean-up everything and exit the Wine process.
38  * This is the back-end of ExitWindows(), called when all windows
39  * have agreed to be terminated.
40  */
41 void EXEC_ExitWindows( int retCode )
42 {
43     /* Do the clean-up stuff */
44
45     WriteOutProfiles();
46     SHELL_SaveRegistry();
47
48     exit( retCode );
49 }
50
51
52 /***********************************************************************
53  *           ExitWindows   (USER.7)
54  */
55 BOOL ExitWindows( DWORD dwReturnCode, WORD wReserved )
56 {
57     int i;
58     BOOL16 result;
59     WND **list, **ppWnd;
60         
61     api_assert("ExitWindows", wReserved == 0);
62     api_assert("ExitWindows", HIWORD(dwReturnCode) == 0);
63
64     /* We have to build a list of all windows first, as in EnumWindows */
65
66     if (!(list = WIN_BuildWinArray( WIN_GetDesktop() ))) return FALSE;
67
68     /* Send a WM_QUERYENDSESSION message to every window */
69
70     for (ppWnd = list, i = 0; *ppWnd; ppWnd++, i++)
71     {
72         /* Make sure that the window still exists */
73         if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
74         if (!SendMessage16( (*ppWnd)->hwndSelf, WM_QUERYENDSESSION, 0, 0 ))
75             break;
76     }
77     result = !(*ppWnd);
78
79     /* Now notify all windows that got a WM_QUERYENDSESSION of the result */
80
81     for (ppWnd = list; i > 0; i--, ppWnd++)
82     {
83         if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
84         SendMessage16( (*ppWnd)->hwndSelf, WM_ENDSESSION, result, 0 );
85     }
86     HeapFree( SystemHeap, 0, list );
87
88     if (result) EXEC_ExitWindows( LOWORD(dwReturnCode) );
89     return FALSE;
90 }
91
92
93 /**********************************************************************
94  *                              WinHelp         [USER.171]
95  */
96 BOOL WinHelp(HWND hWnd, LPSTR lpHelpFile, WORD wCommand, DWORD dwData)
97 {
98         static WORD WM_WINHELP=0;
99         HWND hDest;
100         LPWINHELP lpwh;
101         HANDLE hwh;
102         void *data=0;
103         int size,dsize,nlen;
104         if (wCommand != HELP_QUIT)  /* FIXME */
105             if(WinExec("winhelp.exe -x",SW_SHOWNORMAL)<=32)
106                 return FALSE;
107         /* FIXME: Should be directed yield, to let winhelp open the window */
108         Yield();
109         if(!WM_WINHELP) {
110                 WM_WINHELP=RegisterWindowMessage32A("WM_WINHELP");
111                 if(!WM_WINHELP)
112                         return FALSE;
113         }
114         hDest = FindWindow32A( "MS_WINHELP", NULL );
115         if(!hDest)
116                 return FALSE;
117         switch(wCommand)
118         {
119                 case HELP_CONTEXT:
120                 case HELP_CONTENTS:
121                 case HELP_SETCONTENTS:
122                 case HELP_CONTEXTPOPUP:
123                 case HELP_FORCEFILE:
124                 case HELP_HELPONHELP:
125                 case HELP_QUIT:
126                         dsize=0;
127                         break;
128                 case HELP_KEY:
129                 case HELP_PARTIALKEY:
130                 case HELP_COMMAND:
131                         data = PTR_SEG_TO_LIN(dwData);
132                         dsize = strlen(data)+1;
133                         break;
134                 case HELP_MULTIKEY:
135                         data = PTR_SEG_TO_LIN(dwData);
136                         dsize = ((LPMULTIKEYHELP)data) -> mkSize;
137                         break;
138                 case HELP_SETWINPOS:
139                         data = PTR_SEG_TO_LIN(dwData);
140                         dsize = ((LPHELPWININFO)data) -> wStructSize;
141                         break;
142                 default:
143                         fprintf(stderr,"Unknown help command %d\n",wCommand);
144                         return FALSE;
145         }
146         if(lpHelpFile)
147                 nlen =  strlen(lpHelpFile)+1;
148         else
149                 nlen = 0;
150         size = sizeof(WINHELP) + nlen + dsize;
151         hwh = GlobalAlloc16(0,size);
152         lpwh = GlobalLock16(hwh);
153         lpwh->size = size;
154         lpwh->command = wCommand;
155         if(nlen) {
156                 lpwh->ofsFilename = sizeof(WINHELP);
157                 strcpy(((char*)lpwh) + sizeof(WINHELP),lpHelpFile);
158         }
159         if(dsize) {
160                 memcpy(((char*)lpwh)+sizeof(WINHELP)+nlen,data,dsize);
161                 lpwh->ofsData = sizeof(WINHELP)+nlen;
162         } else
163                 lpwh->ofsData = 0;
164         GlobalUnlock16(hwh);
165         return SendMessage16(hDest,WM_WINHELP,hWnd,hwh);
166 }