Protect GlobalAddAtomA string handling by exception handler (for
[wine] / dlls / kernel / error16.c
1 /*
2  * Log internal errors
3  *
4  * Copyright 1997 Andrew Taylor
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdlib.h>
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <string.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wine/winbase16.h"
29 #include "wine/debug.h"
30
31
32 /* LogParamError and LogError values */
33
34 /* Error modifier bits */
35 #define ERR_WARNING             0x8000
36 #define ERR_PARAM               0x4000
37
38 #define ERR_SIZE_MASK           0x3000
39 #define ERR_BYTE                0x1000
40 #define ERR_WORD                0x2000
41 #define ERR_DWORD               0x3000
42
43
44 /* LogParamError() values */
45
46 /* Generic parameter values */
47 #define ERR_BAD_VALUE           0x6001
48 #define ERR_BAD_FLAGS           0x6002
49 #define ERR_BAD_INDEX           0x6003
50 #define ERR_BAD_DVALUE          0x7004
51 #define ERR_BAD_DFLAGS          0x7005
52 #define ERR_BAD_DINDEX          0x7006
53 #define ERR_BAD_PTR             0x7007
54 #define ERR_BAD_FUNC_PTR        0x7008
55 #define ERR_BAD_SELECTOR        0x6009
56 #define ERR_BAD_STRING_PTR      0x700a
57 #define ERR_BAD_HANDLE          0x600b
58
59 /* KERNEL parameter errors */
60 #define ERR_BAD_HINSTANCE       0x6020
61 #define ERR_BAD_HMODULE         0x6021
62 #define ERR_BAD_GLOBAL_HANDLE   0x6022
63 #define ERR_BAD_LOCAL_HANDLE    0x6023
64 #define ERR_BAD_ATOM            0x6024
65 #define ERR_BAD_HFILE           0x6025
66
67 /* USER parameter errors */
68 #define ERR_BAD_HWND            0x6040
69 #define ERR_BAD_HMENU           0x6041
70 #define ERR_BAD_HCURSOR         0x6042
71 #define ERR_BAD_HICON           0x6043
72 #define ERR_BAD_HDWP            0x6044
73 #define ERR_BAD_CID             0x6045
74 #define ERR_BAD_HDRVR           0x6046
75
76 /* GDI parameter errors */
77 #define ERR_BAD_COORDS          0x7060
78 #define ERR_BAD_GDI_OBJECT      0x6061
79 #define ERR_BAD_HDC             0x6062
80 #define ERR_BAD_HPEN            0x6063
81 #define ERR_BAD_HFONT           0x6064
82 #define ERR_BAD_HBRUSH          0x6065
83 #define ERR_BAD_HBITMAP         0x6066
84 #define ERR_BAD_HRGN            0x6067
85 #define ERR_BAD_HPALETTE        0x6068
86 #define ERR_BAD_HMETAFILE       0x6069
87
88
89 /* LogError() values */
90
91 /* KERNEL errors */
92 #define ERR_GALLOC              0x0001
93 #define ERR_GREALLOC            0x0002
94 #define ERR_GLOCK               0x0003
95 #define ERR_LALLOC              0x0004
96 #define ERR_LREALLOC            0x0005
97 #define ERR_LLOCK               0x0006
98 #define ERR_ALLOCRES            0x0007
99 #define ERR_LOCKRES             0x0008
100 #define ERR_LOADMODULE          0x0009
101
102 /* USER errors */
103 #define ERR_CREATEDLG           0x0040
104 #define ERR_CREATEDLG2          0x0041
105 #define ERR_REGISTERCLASS       0x0042
106 #define ERR_DCBUSY              0x0043
107 #define ERR_CREATEWND           0x0044
108 #define ERR_STRUCEXTRA          0x0045
109 #define ERR_LOADSTR             0x0046
110 #define ERR_LOADMENU            0x0047
111 #define ERR_NESTEDBEGINPAINT    0x0048
112 #define ERR_BADINDEX            0x0049
113 #define ERR_CREATEMENU          0x004a
114
115 /* GDI errors */
116 #define ERR_CREATEDC            0x0080
117 #define ERR_CREATEMETA          0x0081
118 #define ERR_DELOBJSELECTED      0x0082
119 #define ERR_SELBITMAP           0x0083
120
121
122 #define ErrorString(manifest) { manifest, # manifest }
123
124 static const struct {
125         int constant;
126         const char *name;
127 } ErrorStrings[] = {
128
129         ErrorString(ERR_GALLOC),
130         ErrorString(ERR_GREALLOC),
131         ErrorString(ERR_GLOCK),
132         ErrorString(ERR_LALLOC),
133         ErrorString(ERR_LREALLOC),
134         ErrorString(ERR_LLOCK),
135         ErrorString(ERR_ALLOCRES),
136         ErrorString(ERR_LOCKRES),
137         ErrorString(ERR_LOADMODULE),
138         ErrorString(ERR_CREATEDLG),
139         ErrorString(ERR_CREATEDLG2),
140         ErrorString(ERR_REGISTERCLASS),
141         ErrorString(ERR_DCBUSY),
142         ErrorString(ERR_CREATEWND),
143         ErrorString(ERR_STRUCEXTRA),
144         ErrorString(ERR_LOADSTR),
145         ErrorString(ERR_LOADMENU),
146         ErrorString(ERR_NESTEDBEGINPAINT),
147         ErrorString(ERR_BADINDEX),
148         ErrorString(ERR_CREATEMENU),
149         ErrorString(ERR_CREATEDC),
150         ErrorString(ERR_CREATEMETA),
151         ErrorString(ERR_DELOBJSELECTED),
152         ErrorString(ERR_SELBITMAP)
153 };
154
155 static const struct {
156         int constant;
157         const char *name;
158 } ParamErrorStrings[] = {
159
160         ErrorString(ERR_BAD_VALUE),
161         ErrorString(ERR_BAD_FLAGS),
162         ErrorString(ERR_BAD_INDEX),
163         ErrorString(ERR_BAD_DVALUE),
164         ErrorString(ERR_BAD_DFLAGS),
165         ErrorString(ERR_BAD_DINDEX),
166         ErrorString(ERR_BAD_PTR),
167         ErrorString(ERR_BAD_FUNC_PTR),
168         ErrorString(ERR_BAD_SELECTOR),
169         ErrorString(ERR_BAD_STRING_PTR),
170         ErrorString(ERR_BAD_HANDLE),
171         ErrorString(ERR_BAD_HINSTANCE),
172         ErrorString(ERR_BAD_HMODULE),
173         ErrorString(ERR_BAD_GLOBAL_HANDLE),
174         ErrorString(ERR_BAD_LOCAL_HANDLE),
175         ErrorString(ERR_BAD_ATOM),
176         ErrorString(ERR_BAD_HFILE),
177         ErrorString(ERR_BAD_HWND),
178         ErrorString(ERR_BAD_HMENU),
179         ErrorString(ERR_BAD_HCURSOR),
180         ErrorString(ERR_BAD_HICON),
181         ErrorString(ERR_BAD_HDWP),
182         ErrorString(ERR_BAD_CID),
183         ErrorString(ERR_BAD_HDRVR),
184         ErrorString(ERR_BAD_COORDS),
185         ErrorString(ERR_BAD_GDI_OBJECT),
186         ErrorString(ERR_BAD_HDC),
187         ErrorString(ERR_BAD_HPEN),
188         ErrorString(ERR_BAD_HFONT),
189         ErrorString(ERR_BAD_HBRUSH),
190         ErrorString(ERR_BAD_HBITMAP),
191         ErrorString(ERR_BAD_HRGN),
192         ErrorString(ERR_BAD_HPALETTE),
193         ErrorString(ERR_BAD_HMETAFILE)
194 };
195
196 #undef  ErrorString
197 #define ErrorStringCount (sizeof(ErrorStrings) / sizeof(ErrorStrings[0]))
198 #define ParamErrorStringCount (sizeof(ParamErrorStrings) / sizeof(ParamErrorStrings[0]))
199
200 /***********************************************************************
201 *       GetErrorString (internal)
202 */
203 static const char *GetErrorString(UINT16 uErr)
204 {
205   static char buffer[80];
206   unsigned int n;
207
208   for (n = 0; n < ErrorStringCount; n++) {
209     if (uErr == ErrorStrings[n].constant)
210       return ErrorStrings[n].name;
211   }
212
213   sprintf(buffer, "%x", uErr);
214   return buffer;
215 }
216
217
218 /***********************************************************************
219 *       GetParamErrorString (internal)
220 */
221 static const char *GetParamErrorString(UINT16 uErr) {
222         static char buffer[80];
223
224         if (uErr & ERR_WARNING) {
225                 strcpy(buffer, "ERR_WARNING | ");
226                 uErr &= ~ERR_WARNING;
227         } else
228                 buffer[0] = '\0';
229
230         {
231                 unsigned int n;
232
233                 for (n = 0; n < ParamErrorStringCount; n++) {
234                         if (uErr == ParamErrorStrings[n].constant) {
235                                 strcat(buffer, ParamErrorStrings[n].name);
236                                 return buffer;
237                         }
238                 }
239         }
240
241         sprintf(buffer + strlen(buffer), "%x", uErr);
242         return buffer;
243 }
244
245
246 /***********************************************************************
247 *       LogError (KERNEL.324)
248 */
249 VOID WINAPI LogError16(UINT16 uErr, LPVOID lpvInfo)
250 {
251         MESSAGE("(%s, %p)\n", GetErrorString(uErr), lpvInfo);
252 }
253
254
255 /***********************************************************************
256 *       LogParamError (KERNEL.325)
257 */
258 void WINAPI LogParamError16(UINT16 uErr, FARPROC16 lpfn, LPVOID lpvParam)
259 {
260         /* FIXME: is it possible to get the module name/function
261          * from the lpfn param?
262          */
263         MESSAGE("(%s, %p, %p)\n", GetParamErrorString(uErr), lpfn, lpvParam);
264 }
265
266 /***********************************************************************
267 *       K327 (KERNEL.327)
268 */
269 void WINAPI HandleParamError( CONTEXT86 *context )
270 {
271         UINT16 uErr = LOWORD(context->Ebx);
272         FARPROC16 lpfn = (FARPROC16)MAKESEGPTR( context->SegCs, context->Eip );
273         LPVOID lpvParam = (LPVOID)MAKELONG( LOWORD(context->Eax), LOWORD(context->Ecx) );
274
275         LogParamError16( uErr, lpfn, lpvParam );
276
277         if (!(uErr & ERR_WARNING))
278         {
279                 /* Abort current procedure: Unwind stack frame and jump
280                    to error handler (location at [bp-2]) */
281
282                 WORD *stack = MapSL( MAKESEGPTR( context->SegSs, LOWORD(context->Ebp) ));
283                 context->Esp = LOWORD(context->Ebp) - 2;
284                 context->Ebp = stack[0] & 0xfffe;
285
286                 context->Eip = stack[-1];
287
288                 context->Eax = context->Ecx = context->Edx = 0;
289                 context->SegEs = 0;
290         }
291 }