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