Use the right buffer size in SYSPARAMS_Load instead of some random
[wine] / windows / winhelp.c
1 /*
2  * Windows Help
3  *
4  * Copyright 1996 Martin von Loewis
5  *           2002 Eric Pouech
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #ifdef HAVE_UNISTD_H
28 # include <unistd.h>
29 #endif
30 #include "wine/debug.h"
31 #include "winbase.h"
32 #include "wingdi.h"
33 #include "winuser.h"
34 #include "winnls.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(win);
37
38 /* Wine doesn't use the way WinHelp API sends information in Windows, because:
39  * 1/ it's not consistent acrosss Win9x, NT...
40  * 2/ NT implementation is not yet fully understood (and includes some shared
41  *     memory mechanism)
42  * 3/ uses a dynamically allocated message number (WM_WINHELP), which 
43  *    obfuscates the code
44  *
45  * So we use (for now) the simple protocol:
46  * 1/ it's based on copy data
47  * 2/ we tag the message with a magic number, to make it a bit more robust 
48  *   (even if it's not 100% safe)
49  * 3/ data structure (WINHELP) has the same layout that the one used on Win95. 
50  *    This doesn't bring much, except not going to far away from real 
51  *    implementation.
52  *
53  * This means anyway that native winhelp.exe and winhlp32.exe cannot be 
54  * called/manipulated from WinHelp API.
55  */
56 typedef struct
57 {
58     WORD size;
59     WORD command;
60     LONG data;
61     LONG reserved;
62     WORD ofsFilename;
63     WORD ofsData;
64 } WINHELP;
65
66 /* magic number for this message:
67  *  aide means help is French ;-) 
68  *  SOS means ???
69  */
70 #define WINHELP_MAGIC   0xA1DE505
71
72 /**********************************************************************
73  *              WinHelpA (USER32.@)
74  */
75 BOOL WINAPI WinHelpA( HWND hWnd, LPCSTR lpHelpFile, UINT wCommand, ULONG_PTR dwData )
76 {
77     COPYDATASTRUCT      cds;
78     HWND                hDest;
79     int                 size, dsize, nlen;
80     WINHELP*            lpwh;
81
82     hDest = FindWindowA("MS_WINHELP", NULL);
83     if (!hDest) 
84     {
85         if (wCommand == HELP_QUIT) return TRUE;
86         if (WinExec("winhelp.exe -x", SW_SHOWNORMAL) < 32) 
87         {
88             ERR("can't start winhelp.exe -x ?\n");
89             return FALSE;
90         }
91         if (!(hDest = FindWindowA("MS_WINHELP", NULL))) 
92         {
93             FIXME("Did not find a MS_WINHELP Window\n");
94             return FALSE;
95         }
96     }
97
98     switch (wCommand)
99     {
100     case HELP_CONTEXT:
101     case HELP_SETCONTENTS:
102     case HELP_CONTENTS:
103     case HELP_CONTEXTPOPUP:
104     case HELP_FORCEFILE:
105     case HELP_HELPONHELP:
106     case HELP_FINDER:
107     case HELP_QUIT:
108         dsize = 0;
109         break;
110     case HELP_KEY:
111     case HELP_PARTIALKEY:
112     case HELP_COMMAND:
113         dsize = dwData ? strlen((LPSTR)dwData) + 1 : 0;
114         break;
115     case HELP_MULTIKEY:
116         dsize = ((LPMULTIKEYHELPA)dwData)->mkSize;
117         break;
118     case HELP_SETWINPOS:
119         dsize = ((LPHELPWININFOA)dwData)->wStructSize;
120         break;
121     default:
122         FIXME("Unknown help command %d\n", wCommand);
123         return FALSE;
124     }
125     if (lpHelpFile)
126         nlen = strlen(lpHelpFile) + 1;
127     else
128         nlen = 0;
129     size = sizeof(WINHELP) + nlen + dsize;
130
131     lpwh = HeapAlloc(GetProcessHeap(), 0, size);
132     if (!lpwh) return FALSE;
133
134     cds.dwData = WINHELP_MAGIC;
135     cds.cbData = size;
136     cds.lpData = (void*)lpwh;
137
138     lpwh->size = size;
139     lpwh->command = wCommand;
140     lpwh->data = dwData;
141     if (nlen) 
142     {
143         strcpy(((char*)lpwh) + sizeof(WINHELP), lpHelpFile);
144         lpwh->ofsFilename = sizeof(WINHELP);
145     } else
146         lpwh->ofsFilename = 0;
147     if (dsize) 
148     {
149         memcpy(((char*)lpwh) + sizeof(WINHELP) + nlen, (LPSTR)dwData, dsize);
150         lpwh->ofsData = sizeof(WINHELP) + nlen;
151     } else
152         lpwh->ofsData = 0;
153     WINE_TRACE("Sending[%u]: cmd=%u data=%08lx fn=%s\n", 
154                lpwh->size, lpwh->command, lpwh->data,
155                lpwh->ofsFilename ? (LPSTR)lpwh + lpwh->ofsFilename : "");
156
157     return SendMessageA(hDest, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds);
158 }
159
160
161 /**********************************************************************
162  *              WinHelpW (USER32.@)
163  */
164 BOOL WINAPI WinHelpW( HWND hWnd, LPCWSTR helpFile, UINT command, ULONG_PTR dwData )
165 {
166     INT len;
167     LPSTR file;
168     BOOL ret = FALSE;
169
170     if (!helpFile) return WinHelpA( hWnd, NULL, command, dwData );
171
172     len = WideCharToMultiByte( CP_ACP, 0, helpFile, -1, NULL, 0, NULL, NULL );
173     if ((file = HeapAlloc( GetProcessHeap(), 0, len )))
174     {
175         WideCharToMultiByte( CP_ACP, 0, helpFile, -1, file, len, NULL, NULL );
176         ret = WinHelpA( hWnd, file, command, dwData );
177         HeapFree( GetProcessHeap(), 0, file );
178     }
179     return ret;
180 }