Coverage Report

Created: 2026-08-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/guid-utils.c
Line
Count
Source
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
#include "uuid_types.h"
22
23
#ifdef _WIN32
24
#include <tchar.h>
25
#include <windows.h>
26
#include <strsafe.h>
27
#endif
28
29
static int guid_id;
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
/* Wrapper of guid_hash to use in uuid_type_dissector_register() */
73
static unsigned
74
uuid_guid_hash(const void* guid)
75
7.39k
{
76
7.39k
  return guid_hash((const e_guid_t*)guid);
77
7.39k
}
78
79
/* Wrapper of guid_cmp to use in uuid_type_dissector_register() */
80
static gboolean
81
uuid_guid_equal(const void* g1, const void* g2)
82
1.84k
{
83
1.84k
  return (guid_cmp((const e_guid_t*)g1, (const e_guid_t*)g2) == 0);
84
1.84k
}
85
86
/* Wrapper of guids_get_guid_name to use in uuid_type_dissector_register() */
87
static const char*
88
uuid_guid_to_str(void* uuid, wmem_allocator_t* scope)
89
0
{
90
0
  return guids_get_guid_name((const e_guid_t*)uuid, scope);
91
0
}
92
93
void
94
guids_init(void)
95
16
{
96
16
  guid_id = uuid_type_dissector_register("guid_global", uuid_guid_hash, uuid_guid_equal, uuid_guid_to_str);
97
  /* XXX here is a good place to read a config file with wellknown guids */
98
16
}
99
100
void
101
guids_add_guid(const e_guid_t* guid, const char* name)
102
5.00k
{
103
  /* The previous implementation used a wmem_tree with an array
104
   * of 32-bit keys, allowing callers to pass in a pointer to a
105
   * e_guid_t allocated on the stack. To insert into a map, the
106
   * e_guid_t key needs to be copied to heap-allocated memory.
107
   */
108
5.00k
  e_guid_t* guid_key = wmem_new(wmem_epan_scope(), e_guid_t);
109
5.00k
  *guid_key = *guid;
110
5.00k
  uuid_type_insert(guid_id, (void*)guid_key, (void*)name);
111
5.00k
}
112
113
void
114
guids_delete_guid(const e_guid_t* guid)
115
0
{
116
0
  uuid_type_remove_if_present(guid_id, (void*)guid);
117
0
}
118
119
const char*
120
guids_get_guid_name(const e_guid_t* guid, wmem_allocator_t* scope _U_)
121
2.38k
{
122
2.38k
  char* name;
123
#ifdef _WIN32
124
  static char* uuid_name;
125
#endif
126
127
2.38k
  if ((name = (char*)uuid_type_lookup(guid_id, (void*)guid))) {
128
692
    return name;
129
692
  }
130
131
#ifdef _WIN32
132
  /* try to resolve the mapping from the Windows registry */
133
  /* XXX - prefill the resolving database with all the Windows registry entries once at init only (instead of searching each time)? */
134
  uuid_name = wmem_alloc(scope, 128);
135
  if (ResolveWin32UUID(*guid, uuid_name, 128)) {
136
    return uuid_name;
137
  }
138
#endif
139
140
1.69k
  return NULL;
141
2.38k
}
142
143
const char *
144
guids_resolve_guid_to_str(const e_guid_t *guid, wmem_allocator_t *scope)
145
605
{
146
605
  const char *name;
147
148
605
  name=guids_get_guid_name(guid, scope);
149
605
  if(name){
150
406
    return name;
151
406
  }
152
153
199
  return wmem_strdup_printf(scope, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
154
199
        guid->data1, guid->data2, guid->data3,
155
199
        guid->data4[0], guid->data4[1],
156
199
        guid->data4[2], guid->data4[3],
157
199
        guid->data4[4], guid->data4[5],
158
199
        guid->data4[6], guid->data4[7]);
159
605
}
160
161
int guid_cmp(const e_guid_t *g1, const e_guid_t *g2)
162
1.84k
{
163
1.84k
  if (g1->data1 != g2->data1) {
164
720
    return (g1->data1 < g2->data1) ? -1 : 1;
165
720
  }
166
167
1.12k
  if (g1->data2 != g2->data2) {
168
0
    return (g1->data2 < g2->data2) ? -1 : 1;
169
0
  }
170
171
1.12k
  if (g1->data3 != g2->data3) {
172
0
    return (g1->data3 < g2->data3) ? -1 : 1;
173
0
  }
174
175
1.12k
  return memcmp(&g1->data4[0], &g2->data4[0], 8);
176
1.12k
}
177
178
unsigned guid_hash(const e_guid_t *guid)
179
7.39k
{
180
7.39k
  return g_int64_hash((const int64_t *)guid);
181
7.39k
}
182
183
/*
184
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
185
 *
186
 * Local variables:
187
 * c-basic-offset: 8
188
 * tab-width: 8
189
 * indent-tabs-mode: t
190
 * End:
191
 *
192
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
193
 * :indentSize=8:tabSize=8:noTabs=false:
194
 */