forked from osmocom/wireshark
176 lines
5.4 KiB
C
176 lines
5.4 KiB
C
![]() |
/* win32-utils.c
|
||
|
* Win32 utility routines
|
||
|
*
|
||
|
* Wireshark - Network traffic analyzer
|
||
|
* By Gerald Combs <gerald@wireshark.org>
|
||
|
* Copyright 2006 Gerald Combs
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU General Public License
|
||
|
* as published by the Free Software Foundation; either version 2
|
||
|
* of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software
|
||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||
|
*/
|
||
|
|
||
|
#include "win32-utils.h"
|
||
|
|
||
|
/* Quote the argument element if necessary, so that it will get
|
||
|
* reconstructed correctly in the C runtime startup code. Note that
|
||
|
* the unquoting algorithm in the C runtime is really weird, and
|
||
|
* rather different than what Unix shells do. See stdargv.c in the C
|
||
|
* runtime sources (in the Platform SDK, in src/crt).
|
||
|
*
|
||
|
* Stolen from GLib's protect_argv(), an internal routine that quotes
|
||
|
* string in an argument list so that they arguments will be handled
|
||
|
* correctly in the command-line string passed to CreateProcess()
|
||
|
* if that string is constructed by gluing those strings together.
|
||
|
*/
|
||
|
gchar *
|
||
|
protect_arg (const gchar *argv)
|
||
|
{
|
||
|
gchar *new_arg;
|
||
|
const gchar *p = argv;
|
||
|
gchar *q;
|
||
|
gint len = 0;
|
||
|
gboolean need_dblquotes = FALSE;
|
||
|
|
||
|
while (*p) {
|
||
|
if (*p == ' ' || *p == '\t')
|
||
|
need_dblquotes = TRUE;
|
||
|
else if (*p == '"')
|
||
|
len++;
|
||
|
else if (*p == '\\') {
|
||
|
const gchar *pp = p;
|
||
|
|
||
|
while (*pp && *pp == '\\')
|
||
|
pp++;
|
||
|
if (*pp == '"')
|
||
|
len++;
|
||
|
}
|
||
|
len++;
|
||
|
p++;
|
||
|
}
|
||
|
|
||
|
q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
|
||
|
p = argv;
|
||
|
|
||
|
if (need_dblquotes)
|
||
|
*q++ = '"';
|
||
|
|
||
|
while (*p) {
|
||
|
if (*p == '"')
|
||
|
*q++ = '\\';
|
||
|
else if (*p == '\\') {
|
||
|
const gchar *pp = p;
|
||
|
|
||
|
while (*pp && *pp == '\\')
|
||
|
pp++;
|
||
|
if (*pp == '"')
|
||
|
*q++ = '\\';
|
||
|
}
|
||
|
*q++ = *p;
|
||
|
p++;
|
||
|
}
|
||
|
|
||
|
if (need_dblquotes)
|
||
|
*q++ = '"';
|
||
|
*q++ = '\0';
|
||
|
|
||
|
return new_arg;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Generate a string for a Win32 error.
|
||
|
*/
|
||
|
#define ERRBUF_SIZE 1024
|
||
|
const char *
|
||
|
win32strerror(DWORD error)
|
||
|
{
|
||
|
static char errbuf[ERRBUF_SIZE+1];
|
||
|
size_t errlen;
|
||
|
char *p;
|
||
|
|
||
|
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||
|
NULL, error, 0, errbuf, ERRBUF_SIZE, NULL);
|
||
|
|
||
|
/*
|
||
|
* "FormatMessage()" "helpfully" sticks CR/LF at the end of the
|
||
|
* message. Get rid of it.
|
||
|
*/
|
||
|
errlen = strlen(errbuf);
|
||
|
if (errlen >= 2) {
|
||
|
errbuf[errlen - 1] = '\0';
|
||
|
errbuf[errlen - 2] = '\0';
|
||
|
}
|
||
|
p = strchr(errbuf, '\0');
|
||
|
g_snprintf(p, (gulong)(sizeof errbuf - (p-errbuf)), " (%lu)", error);
|
||
|
return errbuf;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Generate a string for a Win32 exception code.
|
||
|
*/
|
||
|
const char *
|
||
|
win32strexception(DWORD exception)
|
||
|
{
|
||
|
static char errbuf[ERRBUF_SIZE+1];
|
||
|
static const struct exception_msg {
|
||
|
int code;
|
||
|
char *msg;
|
||
|
} exceptions[] = {
|
||
|
{ EXCEPTION_ACCESS_VIOLATION, "Access violation" },
|
||
|
{ EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "Array bounds exceeded" },
|
||
|
{ EXCEPTION_BREAKPOINT, "Breakpoint" },
|
||
|
{ EXCEPTION_DATATYPE_MISALIGNMENT, "Data type misalignment" },
|
||
|
{ EXCEPTION_FLT_DENORMAL_OPERAND, "Denormal floating-point operand" },
|
||
|
{ EXCEPTION_FLT_DIVIDE_BY_ZERO, "Floating-point divide by zero" },
|
||
|
{ EXCEPTION_FLT_INEXACT_RESULT, "Floating-point inexact result" },
|
||
|
{ EXCEPTION_FLT_INVALID_OPERATION, "Invalid floating-point operation" },
|
||
|
{ EXCEPTION_FLT_OVERFLOW, "Floating-point overflow" },
|
||
|
{ EXCEPTION_FLT_STACK_CHECK, "Floating-point stack check" },
|
||
|
{ EXCEPTION_FLT_UNDERFLOW, "Floating-point underflow" },
|
||
|
{ EXCEPTION_GUARD_PAGE, "Guard page violation" },
|
||
|
{ EXCEPTION_ILLEGAL_INSTRUCTION, "Illegal instruction" },
|
||
|
{ EXCEPTION_IN_PAGE_ERROR, "Page-in error" },
|
||
|
{ EXCEPTION_INT_DIVIDE_BY_ZERO, "Integer divide by zero" },
|
||
|
{ EXCEPTION_INT_OVERFLOW, "Integer overflow" },
|
||
|
{ EXCEPTION_INVALID_DISPOSITION, "Invalid disposition" },
|
||
|
{ EXCEPTION_INVALID_HANDLE, "Invalid handle" },
|
||
|
{ EXCEPTION_NONCONTINUABLE_EXCEPTION, "Non-continuable exception" },
|
||
|
{ EXCEPTION_PRIV_INSTRUCTION, "Privileged instruction" },
|
||
|
{ EXCEPTION_SINGLE_STEP, "Single-step complete" },
|
||
|
{ EXCEPTION_STACK_OVERFLOW, "Stack overflow" },
|
||
|
{ 0, NULL }
|
||
|
};
|
||
|
#define N_EXCEPTIONS (sizeof exceptions / sizeof exceptions[0])
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < N_EXCEPTIONS; i++) {
|
||
|
if (exceptions[i].code == exception)
|
||
|
return exceptions[i].msg;
|
||
|
}
|
||
|
g_snprintf(errbuf, (gulong)sizeof errbuf, "Exception 0x%08x", exception);
|
||
|
return errbuf;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||
|
*
|
||
|
* Local Variables:
|
||
|
* c-basic-offset: 2
|
||
|
* tab-width: 8
|
||
|
* indent-tabs-mode: nil
|
||
|
* End:
|
||
|
*
|
||
|
* ex: set shiftwidth=2 tabstop=8 expandtab:
|
||
|
* :indentSize=2:tabSize=8:noTabs=true:
|
||
|
*/
|