Added a possibility to let the internal debugger use a separate
[wine] / misc / error.c
1 /*
2  * Log internal errors 
3  *
4  * Copyright 1997 Andrew Taylor
5  */
6
7 #include <stdlib.h>
8 #include <string.h>
9
10 #include "windef.h"
11 #include "stackframe.h"
12 #include "debug.h"
13
14 #define ErrorString(manifest) { manifest, # manifest }
15
16 static const struct {
17         int constant;
18         const char *name;
19 } ErrorStrings[] = {
20
21         ErrorString(ERR_GALLOC),
22         ErrorString(ERR_GREALLOC),
23         ErrorString(ERR_GLOCK),
24         ErrorString(ERR_LALLOC),
25         ErrorString(ERR_LREALLOC),
26         ErrorString(ERR_LLOCK),
27         ErrorString(ERR_ALLOCRES),
28         ErrorString(ERR_LOCKRES),
29         ErrorString(ERR_LOADMODULE),
30         ErrorString(ERR_CREATEDLG),
31         ErrorString(ERR_CREATEDLG2),
32         ErrorString(ERR_REGISTERCLASS),
33         ErrorString(ERR_DCBUSY),
34         ErrorString(ERR_CREATEWND),
35         ErrorString(ERR_STRUCEXTRA),
36         ErrorString(ERR_LOADSTR),
37         ErrorString(ERR_LOADMENU),
38         ErrorString(ERR_NESTEDBEGINPAINT),
39         ErrorString(ERR_BADINDEX),
40         ErrorString(ERR_CREATEMENU),
41         ErrorString(ERR_CREATEDC),
42         ErrorString(ERR_CREATEMETA),
43         ErrorString(ERR_DELOBJSELECTED),
44         ErrorString(ERR_SELBITMAP)
45 };
46
47 static const struct {
48         int constant;
49         const char *name;
50 } ParamErrorStrings[] = {
51
52         ErrorString(ERR_BAD_VALUE),
53         ErrorString(ERR_BAD_FLAGS),
54         ErrorString(ERR_BAD_INDEX),
55         ErrorString(ERR_BAD_DVALUE),
56         ErrorString(ERR_BAD_DFLAGS),
57         ErrorString(ERR_BAD_DINDEX),
58         ErrorString(ERR_BAD_PTR),
59         ErrorString(ERR_BAD_FUNC_PTR),
60         ErrorString(ERR_BAD_SELECTOR),
61         ErrorString(ERR_BAD_STRING_PTR),
62         ErrorString(ERR_BAD_HANDLE),
63         ErrorString(ERR_BAD_HINSTANCE),
64         ErrorString(ERR_BAD_HMODULE),
65         ErrorString(ERR_BAD_GLOBAL_HANDLE),
66         ErrorString(ERR_BAD_LOCAL_HANDLE),
67         ErrorString(ERR_BAD_ATOM),
68         ErrorString(ERR_BAD_HFILE),
69         ErrorString(ERR_BAD_HWND),
70         ErrorString(ERR_BAD_HMENU),
71         ErrorString(ERR_BAD_HCURSOR),
72         ErrorString(ERR_BAD_HICON),
73         ErrorString(ERR_BAD_HDWP),
74         ErrorString(ERR_BAD_CID),
75         ErrorString(ERR_BAD_HDRVR),
76         ErrorString(ERR_BAD_COORDS),
77         ErrorString(ERR_BAD_GDI_OBJECT),
78         ErrorString(ERR_BAD_HDC),
79         ErrorString(ERR_BAD_HPEN),
80         ErrorString(ERR_BAD_HFONT),
81         ErrorString(ERR_BAD_HBRUSH),
82         ErrorString(ERR_BAD_HBITMAP),
83         ErrorString(ERR_BAD_HRGN),
84         ErrorString(ERR_BAD_HPALETTE),
85         ErrorString(ERR_BAD_HMETAFILE)
86 };
87
88 #undef  ErrorString
89 #define ErrorStringCount (sizeof(ErrorStrings) / sizeof(ErrorStrings[0]))
90 #define ParamErrorStringCount (sizeof(ParamErrorStrings) / sizeof(ParamErrorStrings[0]))
91
92 /***********************************************************************
93 *       GetErrorString (internal)
94 */
95 static const char *GetErrorString(UINT16 uErr) 
96 {
97   static char buffer[80];
98   int i;
99
100   for (i = 0; i < ErrorStringCount; i++) {
101     if (uErr == ErrorStrings[i].constant)
102       return ErrorStrings[i].name;
103   }
104
105   sprintf(buffer, "%x", uErr);
106   return buffer;
107 }
108
109
110 /***********************************************************************
111 *       GetParamErrorString (internal)
112 */
113 static const char *GetParamErrorString(UINT16 uErr) {
114         static char buffer[80];
115
116         if (uErr & ERR_WARNING) {
117                 strcpy(buffer, "ERR_WARNING | ");
118                 uErr &= ~ERR_WARNING;
119         } else
120                 buffer[0] = '\0';
121
122         {
123                 int i;
124
125                 for (i = 0; i < ParamErrorStringCount; i++) {
126                         if (uErr == ParamErrorStrings[i].constant) {
127                                 strcat(buffer, ParamErrorStrings[i].name);
128                                 return buffer;
129                         }
130                 }
131         }
132
133         sprintf(buffer + strlen(buffer), "%x", uErr);
134         return buffer;
135 }
136
137
138 /***********************************************************************
139 *       LogError (KERNEL.324)
140 */
141 VOID WINAPI LogError16(UINT16 uErr, LPVOID lpvInfo)
142 {
143         MSG("(%s, %p)\n", GetErrorString(uErr), lpvInfo);
144 }
145
146
147 /***********************************************************************
148 *       LogParamError (KERNEL.325)
149 */
150 void WINAPI LogParamError16(UINT16 uErr, FARPROC16 lpfn, LPVOID lpvParam)
151 {
152         /* FIXME: is it possible to get the module name/function
153          * from the lpfn param?
154          */
155         MSG("(%s, %p, %p)\n", GetParamErrorString(uErr), lpfn, lpvParam);
156 }
157
158 /***********************************************************************
159 *       HandleParamError (KERNEL.327)
160 */
161 void WINAPI HandleParamError( CONTEXT *context )
162 {
163         UINT16 uErr = BX_reg( context );
164         FARPROC16 lpfn = (FARPROC16)PTR_SEG_OFF_TO_SEGPTR( CS_reg(context),
165                                                            EIP_reg(context) );
166         LPVOID lpvParam = (LPVOID)MAKELONG( AX_reg( context ), 
167                                             CX_reg( context ) );
168         
169         LogParamError16( uErr, lpfn, lpvParam );
170
171         if (!(uErr & ERR_WARNING))
172         {
173                 /* Abort current procedure: Unwind stack frame and jump
174                    to error handler (location at [bp-2]) */
175
176                 WORD *stack = PTR_SEG_OFF_TO_LIN( SS_reg( context ), 
177                                                   BP_reg( context ));
178                 SP_reg( context ) = BP_reg( context ) - 2;
179                 BP_reg( context ) = stack[0] & 0xfffe;
180
181                 IP_reg( context ) = stack[-1];
182
183                 EAX_reg( context ) = ECX_reg( context ) = EDX_reg( context ) = 0;
184                 ES_reg( context) = 0;
185         }
186 }
187