source: trunk/kitgen/8.x/libusb-win32/error.c@ 199

Last change on this file since 199 was 175, checked in by demin, 12 years ago

initial commit

File size: 10.4 KB
Line 
1/* Error & Logging functions
2
3 Copyright (C) 2010 Travis Robinson. <libusbdotnet@gmail.com>
4 website: http://sourceforge.net/projects/libusb-win32
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with this program; if not, please visit www.gnu.org.
18*/
19
20#include "error.h"
21#include <errno.h>
22#include <string.h>
23#include <stdio.h>
24
25#if IS_DRIVER
26 #ifdef __GNUC__
27 #define OBJ_KERNEL_HANDLE 0x00000200L
28 #include <ddk/usb100.h>
29 #include <ddk/usbdi.h>
30 #include <ddk/winddk.h>
31 #include "usbdlib_gcc.h"
32 #else
33 #include <ntddk.h>
34 #endif
35#else
36 #include <windows.h>
37#endif
38
39#define USB_ERROR_BEGIN 500000
40
41#ifndef LOG_APPNAME
42#define LOG_APPNAME "LOG_APPNAME define missing"
43#endif
44
45#define GetLogLevel(UsbLogLevel) ((UsbLogLevel & LOG_LEVEL_MASK)>LOG_LEVEL_MAX?LOG_LEVEL_MAX:UsbLogLevel & LOG_LEVEL_MASK)
46#define GetLogOuput(LogOutputType) (LogOutputType>0?(_LOG_OUTPUT_TYPE & LogOutputType):1)
47
48void usb_err_v (const char* function, const char* format, va_list args);
49void usb_wrn_v (const char* function, const char* format, va_list args);
50void usb_msg_v (const char* function, const char* format, va_list args);
51void usb_dbg_v (const char* function, const char* format, va_list args);
52
53void usb_log_v (enum USB_LOG_LEVEL level, const char* function, const char* format, va_list args);
54void _usb_log (enum USB_LOG_LEVEL level, const char* app_name, const char* function, const char* format, ...);
55void _usb_log_v (enum USB_LOG_LEVEL level, const char* app_name, const char* function, const char* format, va_list args);
56
57static int usb_log_def_handler(enum USB_LOG_LEVEL level,
58 const char* app_name,
59 const char* prefix,
60 const char* func,
61 int app_prefix_func_end,
62 char* message,
63 int message_length);
64
65#define STRIP_PREFIX(stringSrc, stringPrefix) \
66 (strstr(stringSrc,stringPrefix)==stringSrc?stringSrc+strlen(stringPrefix):stringSrc)
67
68static const char *log_level_string[LOG_LEVEL_MAX+1] =
69{
70 "off",
71 "err",
72 "wrn",
73 "",
74 "dbg",
75
76 "unknown",
77};
78
79static const char *skipped_function_prefix_list[] =
80{
81 "usb_registry_",
82 "usb_",
83 NULL
84};
85
86int usb_error_errno = 0;
87log_hander_t user_log_hander = NULL;
88
89#if (defined(_DEBUG) || defined(DEBUG) || defined(DBG))
90int __usb_log_level = LOG_LEVEL_MAX;
91#else
92int __usb_log_level = LOG_OFF;
93#endif
94
95usb_error_type_t usb_error_type = USB_ERROR_TYPE_NONE;
96
97const char** skipped_function_prefix = skipped_function_prefix_list;
98
99#if !IS_DRIVER
100
101char usb_error_str[LOGBUF_SIZE] = "";
102
103char *usb_strerror(void)
104{
105 switch (usb_error_type)
106 {
107 case USB_ERROR_TYPE_NONE:
108 return "No error";
109 case USB_ERROR_TYPE_STRING:
110 return usb_error_str;
111 case USB_ERROR_TYPE_ERRNO:
112 if (usb_error_errno > -USB_ERROR_BEGIN)
113 return strerror(usb_error_errno);
114 else
115 /* Any error we don't know falls under here */
116 return "Unknown error";
117 }
118
119 return "Unknown error";
120}
121
122/* returns Windows' last error in a human readable form */
123const char *usb_win_error_to_string(void)
124{
125 static char tmp[LOGBUF_SIZE];
126
127 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
128 LANG_USER_DEFAULT, tmp, sizeof(tmp) - 1, NULL);
129
130 return tmp;
131}
132
133
134int usb_win_error_to_errno(void)
135{
136 switch (GetLastError())
137 {
138 case ERROR_SUCCESS:
139 return 0;
140 case ERROR_INVALID_PARAMETER:
141 return EINVAL;
142 case ERROR_SEM_TIMEOUT:
143 case ERROR_OPERATION_ABORTED:
144 return ETRANSFER_TIMEDOUT;
145 case ERROR_NOT_ENOUGH_MEMORY:
146 return ENOMEM;
147 default:
148 return EIO;
149 }
150}
151
152#endif
153
154void usb_err(const char* function, const char* format, ...)
155{
156 va_list args;
157 va_start(args, format);
158 usb_err_v(function, format, args);
159 va_end(args);
160}
161void usb_wrn(const char* function, const char* format, ...)
162{
163 va_list args;
164 va_start(args, format);
165 usb_wrn_v(function, format, args);
166 va_end(args);
167}
168
169void usb_msg(const char* function, const char* format, ...)
170{
171 va_list args;
172 va_start(args, format);
173 usb_msg_v(function, format, args);
174 va_end(args);
175}
176
177void usb_dbg(const char* function, const char* format, ...)
178{
179 va_list args;
180 va_start(args, format);
181 usb_dbg_v(function, format, args);
182 va_end(args);
183}
184
185void usb_log(enum USB_LOG_LEVEL level, const char* function, const char* format, ...)
186{
187 va_list args;
188 va_start(args, format);
189 usb_log_v(level, function, format, args);
190 va_end(args);
191}
192
193void usb_err_v(const char* function, const char* format, va_list args)
194{
195 usb_log_v(LOG_ERROR, function, format, args);
196}
197
198void usb_wrn_v(const char* function, const char* format, va_list args)
199{
200 usb_log_v(LOG_WARNING, function, format, args);
201}
202
203void usb_msg_v(const char* function, const char* format, va_list args)
204{
205 usb_log_v(LOG_INFO, function, format, args);
206}
207
208void usb_dbg_v(const char* function, const char* format, va_list args)
209{
210 usb_log_v(LOG_DEBUG, function, format, args);
211}
212
213void usb_log_v(enum USB_LOG_LEVEL level, const char* function, const char* format, va_list args)
214{
215 _usb_log_v(level, LOG_APPNAME, function, format, args);
216}
217
218void _usb_log(enum USB_LOG_LEVEL level, const char* app_name, const char* function, const char* format, ...)
219{
220 va_list args;
221 va_start(args, format);
222 _usb_log_v(level, app_name, function, format, args);
223 va_end(args);
224}
225
226void _usb_log_v(enum USB_LOG_LEVEL level,
227 const char* app_name,
228 const char* function,
229 const char* format,
230 va_list args)
231{
232
233 char local_buffer[LOGBUF_SIZE];
234 int totalCount, count;
235 const char* prefix;
236 const char* func;
237 char* buffer;
238 int masked_level;
239 int app_prefix_func_end;
240#ifndef LOG_STYLE_SHORT
241 const char** skip_list = NULL;
242#endif
243
244 masked_level = GetLogLevel(level);
245
246 if (__usb_log_level < masked_level && masked_level != LOG_ERROR) return;
247 buffer = local_buffer;
248 totalCount = 0;
249 count = 0;
250 prefix = log_level_string[masked_level];
251 func = function;
252 app_prefix_func_end = 0;
253
254 if (masked_level > LOG_LEVEL_MAX) masked_level = LOG_LEVEL_MAX;
255
256 if ((level & LOG_RAW) == LOG_RAW)
257 {
258 count = _vsnprintf(buffer, LOGBUF_SIZE-1, format, args);
259 if (count > 0)
260 {
261 buffer += count;
262 totalCount += count;
263 }
264 }
265 else
266 {
267#ifdef LOG_STYLE_SHORT
268 if ((prefix) && strlen(prefix))
269 {
270 count = _snprintf(buffer, (LOGBUF_SIZE-1), "%s: ", prefix);
271 }
272 else
273 {
274 count = 0;
275 }
276 func = "";
277#else
278 func = function;
279
280 if (func)
281 {
282 // strip some prefixes to shorten function names
283 skip_list=skipped_function_prefix;
284 while(*skip_list && ((func)) && func[0])
285 {
286 func = STRIP_PREFIX(func,skip_list[0]);
287 skip_list++;
288 }
289 }
290
291 if(!func) func="none";
292
293 // print app name, level string and short function name
294 if ((prefix) && strlen(prefix))
295 {
296 count = _snprintf(buffer, (LOGBUF_SIZE-1), "%s:%s [%s] ", app_name, prefix, func);
297 }
298 else
299 {
300 count = _snprintf(buffer, (LOGBUF_SIZE-1), "%s:[%s] ", app_name, func);
301 }
302#endif
303
304 if (count >= 0)
305 {
306 app_prefix_func_end = count;
307 buffer += count;
308 totalCount += count;
309 count = _vsnprintf(buffer, (LOGBUF_SIZE-1) - totalCount, format, args);
310 if (count > 0)
311 {
312 buffer += count;
313 totalCount += count;
314 }
315 }
316 }
317
318 if (count < 0)
319 totalCount = LOGBUF_SIZE - 1;
320
321 // make sure its null terminated
322 local_buffer[totalCount] = 0;
323
324#if (!IS_DRIVER)
325 if (masked_level == LOG_ERROR)
326 {
327 // if this is an error message then store it
328 strncpy(usb_error_str, local_buffer, totalCount);
329 usb_error_str[totalCount] = '\0';
330 usb_error_type = USB_ERROR_TYPE_STRING;
331 }
332#endif
333
334 if (user_log_hander)
335 {
336 if (user_log_hander(level, app_name, prefix, func, app_prefix_func_end, local_buffer, totalCount))
337 return;
338 }
339 if (__usb_log_level >= masked_level)
340 {
341 usb_log_def_handler(level, app_name, prefix, func, app_prefix_func_end, local_buffer, totalCount);
342 }
343}
344
345void usb_log_set_level(enum USB_LOG_LEVEL level)
346{
347 // Debug builds of the driver force all messages on; all the time;
348 // Application can no longer change this.
349 //
350#if (defined(_DEBUG) || defined(DEBUG) || defined(DBG))
351 __usb_log_level = LOG_LEVEL_MAX;
352#else
353 __usb_log_level = level > LOG_LEVEL_MAX ? LOG_LEVEL_MAX : level;
354#endif
355}
356
357int usb_log_get_level()
358{
359 return __usb_log_level;
360}
361
362/* Default log handler
363*/
364static int usb_log_def_handler(enum USB_LOG_LEVEL level,
365 const char* app_name,
366 const char* prefix,
367 const char* func,
368 int app_prefix_func_end,
369 char* message,
370 int message_length)
371{
372#if IS_DRIVER
373 DbgPrint("%s",message);
374#else
375 #if GetLogOuput(LOG_OUTPUT_TYPE_FILE)
376 FILE* file;
377 file = fopen(LOG_FILE_PATH,"a");
378 if (file)
379 {
380 fwrite(message,1,strlen(message),file);
381 fflush(file);
382 fclose(file);
383 }
384 #endif
385
386 #if GetLogOuput(LOG_OUTPUT_TYPE_STDERR)
387 fprintf(stderr, "%s", message);
388 #endif
389
390 #if GetLogOuput(LOG_OUTPUT_TYPE_DEBUGWINDOW)
391 OutputDebugStringA(message);
392 #endif
393
394
395 #if GetLogOuput(LOG_OUTPUT_TYPE_MSGBOX)
396 if (GetLogLevel(level)==LOG_ERROR)
397 {
398 message[app_prefix_func_end-1]='\0';
399 MessageBoxA(NULL,message+strlen(message),message,MB_OK|MB_ICONERROR);
400 }
401 #endif
402
403#endif // IS_DRIVER
404
405 return 1;
406}
407
408void usb_log_set_handler(log_hander_t log_hander)
409{
410 user_log_hander = log_hander;
411}
412
413log_hander_t usb_log_get_handler(void)
414{
415 return user_log_hander;
416}
Note: See TracBrowser for help on using the repository browser.