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