Coverage Report

Created: 2025-08-04 07:15

/src/wireshark/epan/guid-utils.c
Line
Count
Source (jump to first uncovered line)
1
/* guid-utils.c
2
 * GUID handling
3
 *
4
 * Wireshark - Network traffic analyzer
5
 * By Gerald Combs <gerald@wireshark.org>
6
 *
7
 * Copyright 1998 Gerald Combs
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 */
11
12
#include "config.h"
13
14
#include <string.h>
15
16
#include <glib.h>
17
#include <epan/epan.h>
18
#include <wsutil/unicode-utils.h>
19
#include <epan/wmem_scopes.h>
20
#include "guid-utils.h"
21
22
#ifdef _WIN32
23
#include <tchar.h>
24
#include <windows.h>
25
#include <strsafe.h>
26
#endif
27
28
static wmem_tree_t *guid_to_name_tree;
29
30
31
#ifdef _WIN32
32
/* try to resolve an DCE/RPC interface name to its name using the Windows registry entries */
33
/* XXX - might be better to fill all interfaces into our database at startup instead of searching each time */
34
static int
35
ResolveWin32UUID(e_guid_t if_id, char *uuid_name, int uuid_name_max_len)
36
{
37
  TCHAR *reg_uuid_name;
38
  HKEY hKey = NULL;
39
  DWORD uuid_max_size = MAX_PATH;
40
  TCHAR *reg_uuid_str;
41
42
  reg_uuid_name=wmem_alloc(NULL, (MAX_PATH*sizeof(TCHAR))+1);
43
  reg_uuid_str=wmem_alloc(NULL, (MAX_PATH*sizeof(TCHAR))+1);
44
45
  if(uuid_name_max_len < 2){
46
    return 0;
47
  }
48
  reg_uuid_name[0] = '\0';
49
  StringCchPrintf(reg_uuid_str, MAX_PATH, _T("SOFTWARE\\Classes\\Interface\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"),
50
      if_id.data1, if_id.data2, if_id.data3,
51
      if_id.data4[0], if_id.data4[1],
52
      if_id.data4[2], if_id.data4[3],
53
      if_id.data4[4], if_id.data4[5],
54
      if_id.data4[6], if_id.data4[7]);
55
  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg_uuid_str, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {
56
    if (RegQueryValueEx(hKey, NULL, NULL, NULL, (LPBYTE)reg_uuid_name, &uuid_max_size) == ERROR_SUCCESS && uuid_max_size <= MAX_PATH) {
57
      snprintf(uuid_name, uuid_name_max_len, "%s", utf_16to8(reg_uuid_name));
58
      RegCloseKey(hKey);
59
      wmem_free(NULL, reg_uuid_name);
60
      wmem_free(NULL, reg_uuid_str);
61
      return (int) strlen(uuid_name);
62
    }
63
    RegCloseKey(hKey);
64
  }
65
  wmem_free(NULL, reg_uuid_name);
66
  wmem_free(NULL, reg_uuid_str);
67
  return 0; /* we didn't find anything anyhow. Please don't use the string! */
68
69
}
70
#endif
71
72
73
/* store a guid to name mapping */
74
void
75
guids_add_guid(const e_guid_t *guid, const char *name)
76
4.36k
{
77
4.36k
  wmem_tree_key_t guidkey[2];
78
4.36k
  uint32_t g[4];
79
80
4.36k
  g[0]=guid->data1;
81
82
4.36k
  g[1]=guid->data2;
83
4.36k
  g[1]<<=16;
84
4.36k
  g[1]|=guid->data3;
85
86
4.36k
  g[2]=guid->data4[0];
87
4.36k
  g[2]<<=8;
88
4.36k
  g[2]|=guid->data4[1];
89
4.36k
  g[2]<<=8;
90
4.36k
  g[2]|=guid->data4[2];
91
4.36k
  g[2]<<=8;
92
4.36k
  g[2]|=guid->data4[3];
93
94
4.36k
  g[3]=guid->data4[4];
95
4.36k
  g[3]<<=8;
96
4.36k
  g[3]|=guid->data4[5];
97
4.36k
  g[3]<<=8;
98
4.36k
  g[3]|=guid->data4[6];
99
4.36k
  g[3]<<=8;
100
4.36k
  g[3]|=guid->data4[7];
101
102
4.36k
  guidkey[0].key=g;
103
4.36k
  guidkey[0].length=4;
104
4.36k
  guidkey[1].length=0;
105
106
4.36k
  wmem_tree_insert32_array(guid_to_name_tree, &guidkey[0], (char *) name);
107
4.36k
}
108
109
/* remove a guid to name mapping */
110
void
111
guids_delete_guid(const e_guid_t *guid)
112
0
{
113
0
  wmem_tree_key_t guidkey[2];
114
0
  uint32_t g[4];
115
116
0
  g[0] = guid->data1;
117
118
0
  g[1] = guid->data2;
119
0
  g[1] <<= 16;
120
0
  g[1] |= guid->data3;
121
122
0
  g[2] = guid->data4[0];
123
0
  g[2] <<= 8;
124
0
  g[2] |= guid->data4[1];
125
0
  g[2] <<= 8;
126
0
  g[2] |= guid->data4[2];
127
0
  g[2] <<= 8;
128
0
  g[2] |= guid->data4[3];
129
130
0
  g[3] = guid->data4[4];
131
0
  g[3] <<= 8;
132
0
  g[3] |= guid->data4[5];
133
0
  g[3] <<= 8;
134
0
  g[3] |= guid->data4[6];
135
0
  g[3] <<= 8;
136
0
  g[3] |= guid->data4[7];
137
138
0
  guidkey[0].key = g;
139
0
  guidkey[0].length = 4;
140
0
  guidkey[1].length = 0;
141
142
0
  void *data = wmem_tree_lookup32_array(guid_to_name_tree, &guidkey[0]);
143
144
0
  if (data != NULL) {
145
    // This will "remove" the entry by setting its data to NULL
146
0
    wmem_tree_insert32_array(guid_to_name_tree, &guidkey[0], NULL);
147
0
  }
148
149
0
}
150
151
/* retrieve the registered name for this GUID; uses the scope for the fallback case only */
152
const char *
153
guids_get_guid_name(const e_guid_t *guid, wmem_allocator_t *scope _U_)
154
351
{
155
351
  wmem_tree_key_t guidkey[2];
156
351
  uint32_t g[4];
157
351
  char *name;
158
#ifdef _WIN32
159
  static char *uuid_name;
160
#endif
161
162
351
  g[0]=guid->data1;
163
164
351
  g[1]=guid->data2;
165
351
  g[1]<<=16;
166
351
  g[1]|=guid->data3;
167
168
351
  g[2]=guid->data4[0];
169
351
  g[2]<<=8;
170
351
  g[2]|=guid->data4[1];
171
351
  g[2]<<=8;
172
351
  g[2]|=guid->data4[2];
173
351
  g[2]<<=8;
174
351
  g[2]|=guid->data4[3];
175
176
351
  g[3]=guid->data4[4];
177
351
  g[3]<<=8;
178
351
  g[3]|=guid->data4[5];
179
351
  g[3]<<=8;
180
351
  g[3]|=guid->data4[6];
181
351
  g[3]<<=8;
182
351
  g[3]|=guid->data4[7];
183
184
351
  guidkey[0].key=g;
185
351
  guidkey[0].length=4;
186
351
  guidkey[1].length=0;
187
188
351
  if((name = (char *)wmem_tree_lookup32_array(guid_to_name_tree, &guidkey[0]))){
189
102
    return name;
190
102
  }
191
192
#ifdef _WIN32
193
  /* try to resolve the mapping from the Windows registry */
194
  /* XXX - prefill the resolving database with all the Windows registry entries once at init only (instead of searching each time)? */
195
  uuid_name=wmem_alloc(scope, 128);
196
  if(ResolveWin32UUID(*guid, uuid_name, 128)) {
197
    return uuid_name;
198
  }
199
#endif
200
201
249
  return NULL;
202
351
}
203
204
205
void
206
guids_init(void)
207
14
{
208
14
  guid_to_name_tree=wmem_tree_new(wmem_epan_scope());
209
  /* XXX here is a good place to read a config file with wellknown guids */
210
14
}
211
212
213
/* Tries to match a guid against its name.
214
   Returns the associated string ptr on a match.
215
   Formats uuid number and returns the resulting string via wmem scope, if name is unknown.
216
   (derived from val_to_str) */
217
const char *
218
guids_resolve_guid_to_str(const e_guid_t *guid, wmem_allocator_t *scope)
219
97
{
220
97
  const char *name;
221
222
97
  name=guids_get_guid_name(guid, scope);
223
97
  if(name){
224
60
    return name;
225
60
  }
226
227
37
  return wmem_strdup_printf(scope, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
228
37
        guid->data1, guid->data2, guid->data3,
229
37
        guid->data4[0], guid->data4[1],
230
37
        guid->data4[2], guid->data4[3],
231
37
        guid->data4[4], guid->data4[5],
232
37
        guid->data4[6], guid->data4[7]);
233
97
}
234
235
int guid_cmp(const e_guid_t *g1, const e_guid_t *g2)
236
0
{
237
0
  if (g1->data1 != g2->data1) {
238
0
    return (g1->data1 < g2->data1) ? -1 : 1;
239
0
  }
240
241
0
  if (g1->data2 != g2->data2) {
242
0
    return (g1->data2 < g2->data2) ? -1 : 1;
243
0
  }
244
245
0
  if (g1->data3 != g2->data3) {
246
0
    return (g1->data3 < g2->data3) ? -1 : 1;
247
0
  }
248
249
0
  return memcmp(&g1->data4[0], &g2->data4[0], 8);
250
0
}
251
252
unsigned guid_hash(const e_guid_t *guid)
253
0
{
254
0
  return g_int64_hash((const int64_t *)guid);
255
0
}
256
257
/*
258
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
259
 *
260
 * Local variables:
261
 * c-basic-offset: 8
262
 * tab-width: 8
263
 * indent-tabs-mode: t
264
 * End:
265
 *
266
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
267
 * :indentSize=8:tabSize=8:noTabs=false:
268
 */