summaryrefslogtreecommitdiff
path: root/src/pmdas/etw/util.c
blob: 19869e6a66419ab846b6f1d0fe95703acdfa921b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*
 * Event Trace for Windows utility routines.
 *
 * Copyright (c) 2011, Nathan Scott.  All Rights Reserved.
 *
 * 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.
 */

#define INITGUID
#include <pmapi.h>
#include <impl.h>
#include <tdh.h>
#include <evntrace.h>
#include "util.h"

struct {
    ULONG flag;
    char  *name;
} kernelFlags[] = {
    { EVENT_TRACE_FLAG_PROCESS, "process" },
    { EVENT_TRACE_FLAG_THREAD, "thread" },
    { EVENT_TRACE_FLAG_IMAGE_LOAD, "image_load" },
    { EVENT_TRACE_FLAG_DISK_IO, "disk_io"  },
    { EVENT_TRACE_FLAG_DISK_FILE_IO, "disk_file_io" },
    { EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS, "memory_page_faults" },
    { EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS, "memory_hard_faults" },
    { EVENT_TRACE_FLAG_NETWORK_TCPIP, "network_tcpip" },
    { EVENT_TRACE_FLAG_REGISTRY, "registry" },
    { EVENT_TRACE_FLAG_DBGPRINT, "dbgprint" },
    { EVENT_TRACE_FLAG_PROCESS_COUNTERS, "process_counters" },
    { EVENT_TRACE_FLAG_CSWITCH, "cswitch" },
    { EVENT_TRACE_FLAG_DPC, "dpc" },
    { EVENT_TRACE_FLAG_INTERRUPT, "interrupt" },
    { EVENT_TRACE_FLAG_SYSTEMCALL, "syscall" },
    { EVENT_TRACE_FLAG_DISK_IO_INIT, "disk_io_init" },
    { EVENT_TRACE_FLAG_ALPC, "alpc" },
    { EVENT_TRACE_FLAG_SPLIT_IO, "split_io" },
    { EVENT_TRACE_FLAG_DRIVER, "driver" },
    { EVENT_TRACE_FLAG_PROFILE, "profile" },
    { EVENT_TRACE_FLAG_FILE_IO, "file_io" },
    { EVENT_TRACE_FLAG_FILE_IO_INIT, "file_io_init" },
    { EVENT_TRACE_FLAG_DISPATCHER, "dispatcher" },
    { EVENT_TRACE_FLAG_VIRTUAL_ALLOC, "virtual_alloc" },
    { EVENT_TRACE_FLAG_EXTENSION, "extension" },
    { EVENT_TRACE_FLAG_FORWARD_WMI, "forward_wmi" },
    { EVENT_TRACE_FLAG_ENABLE_RESERVE, "enable_reserve" },
};

void
dumpKernelTraceFlags(FILE *output, const char *prefix, const char *suffix)
{
    int i;

    for (i = 0; i < sizeof(kernelFlags)/sizeof(kernelFlags[0]); i++)
	fprintf(output, "%s%s%s", prefix, kernelFlags[i].name,
		(i+1 == sizeof(kernelFlags)/sizeof(kernelFlags[0])) ?
		"\0" : suffix);
}

ULONG
kernelTraceFlag(const char *name)
{
    int i;

    for (i = 0; i < sizeof(kernelFlags)/sizeof(kernelFlags[0]); i++)
	if (strcmp(kernelFlags[i].name, name) == 0)
	    return kernelFlags[i].flag;
    fprintf(stderr, "Unrecognised kernel trace flag: %s\n", name);
    fprintf(stderr, "List of all known options:\n");
    dumpKernelTraceFlags(stderr, "\t", "\n");
    fprintf(stderr, "\n\n");
    exit(1);
}

const char *
eventPropertyFlags(USHORT flags)
{
    if (flags & EVENT_HEADER_PROPERTY_XML)
	return "XML";
    if (flags & EVENT_HEADER_PROPERTY_FORWARDED_XML)
	return "forwarded XML";
    if (flags & EVENT_HEADER_PROPERTY_LEGACY_EVENTLOG)
	return "legacy WMI MOF";
    return "none";
}

const char *
eventHeaderFlags(USHORT flags)
{
    static char buffer[128];
    char *p = &buffer[0];

    *p = '\0';
    if (flags & EVENT_HEADER_FLAG_EXTENDED_INFO)
	strcat(p, "extended info,");
    if (flags & EVENT_HEADER_FLAG_PRIVATE_SESSION)
	strcat(p, "private session,");
    if (flags & EVENT_HEADER_FLAG_STRING_ONLY)
	strcat(p, "string,");
    if (flags & EVENT_HEADER_FLAG_TRACE_MESSAGE)
	strcat(p, "TraceMessage,");
    if (flags & EVENT_HEADER_FLAG_NO_CPUTIME)
	strcat(p, "no cputime,");
    if (flags & EVENT_HEADER_FLAG_32_BIT_HEADER)
	strcat(p, "32bit,");
    if (flags & EVENT_HEADER_FLAG_64_BIT_HEADER)
	strcat(p, "64bit,");
    if (flags & EVENT_HEADER_FLAG_CLASSIC_HEADER)
	strcat(p, "classic,");
    buffer[strlen(buffer)-1] = '\0';
    return buffer;
}

const char *
tdherror(ULONG code)
{
    switch (code){
    case ERROR_ACCESS_DENIED:
    	return "Insufficient privileges for requested operation";
    case ERROR_ALREADY_EXISTS:
    	return "A sessions with the same name or GUID already exists";
    case ERROR_BAD_LENGTH:
        return "Insufficient space or size for a parameter";
    case ERROR_BAD_PATHNAME:
        return "Given path parameter is not valid";
    case ERROR_CANCELLED:
    	return "Consumer cancelled processing via buffer callback";
    case ERROR_FILE_NOT_FOUND:
    	return "Unable to find the requested file";
    case ERROR_INSUFFICIENT_BUFFER:
    	return "Size of buffer is too small";
    case ERROR_INVALID_HANDLE:
    	return "Element of array is not a valid event tracing session handle";
    case ERROR_INVALID_PARAMETER:
    	return "One or more of the parameters is not valid";
    case ERROR_INVALID_TIME:
    	return "EndTime is less than StartTime";
    case ERROR_NOACCESS:
    	return "An exception occurred in one of the event callback routines";
    case ERROR_NOT_FOUND:
    	return "Requested class or field type not found";
    case ERROR_NOT_SUPPORTED:
    	return "The requested field type is not supported";
    case ERROR_OUTOFMEMORY:
	return "Insufficient memory";
    case ERROR_WMI_INSTANCE_NOT_FOUND:
    	return "Session from which realtime events to be consumed not running";
    case ERROR_WMI_ALREADY_ENABLED:
    	return "Handle array contains more than one realtime session handle";
    case ERROR_SUCCESS:
    	return "Success";
    }
    return strerror(code);
}

const char *
strguid(LPGUID guidPointer)
{
    static char stringBuffer[64];

    snprintf(stringBuffer, sizeof(stringBuffer),
		"{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
	       guidPointer->Data1, guidPointer->Data2, guidPointer->Data3,
	       guidPointer->Data4[0], guidPointer->Data4[1],
	       guidPointer->Data4[2], guidPointer->Data4[3],
	       guidPointer->Data4[4], guidPointer->Data4[5],
	       guidPointer->Data4[6], guidPointer->Data4[7]);
    return stringBuffer;
}

void *
BufferAllocate(ULONG size)
{
    return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
}

void
BufferFree(void *buffer)
{
    if (buffer)
	HeapFree(GetProcessHeap(), 0, buffer);
}