Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / guid-utils.c
blob2a5d2ff244a039e693106855978bfe441fd3cbe1
1 /* guid-utils.c
2 * GUID handling
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "config.h"
14 #include <string.h>
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"
22 #ifdef _WIN32
23 #include <tchar.h>
24 #include <windows.h>
25 #include <strsafe.h>
26 #endif
28 static wmem_tree_t *guid_to_name_tree;
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)
37 TCHAR *reg_uuid_name;
38 HKEY hKey = NULL;
39 DWORD uuid_max_size = MAX_PATH;
40 TCHAR *reg_uuid_str;
42 reg_uuid_name=wmem_alloc(NULL, (MAX_PATH*sizeof(TCHAR))+1);
43 reg_uuid_str=wmem_alloc(NULL, (MAX_PATH*sizeof(TCHAR))+1);
45 if(uuid_name_max_len < 2){
46 return 0;
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);
63 RegCloseKey(hKey);
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! */
70 #endif
73 /* store a guid to name mapping */
74 void
75 guids_add_guid(const e_guid_t *guid, const char *name)
77 wmem_tree_key_t guidkey[2];
78 uint32_t g[4];
80 g[0]=guid->data1;
82 g[1]=guid->data2;
83 g[1]<<=16;
84 g[1]|=guid->data3;
86 g[2]=guid->data4[0];
87 g[2]<<=8;
88 g[2]|=guid->data4[1];
89 g[2]<<=8;
90 g[2]|=guid->data4[2];
91 g[2]<<=8;
92 g[2]|=guid->data4[3];
94 g[3]=guid->data4[4];
95 g[3]<<=8;
96 g[3]|=guid->data4[5];
97 g[3]<<=8;
98 g[3]|=guid->data4[6];
99 g[3]<<=8;
100 g[3]|=guid->data4[7];
102 guidkey[0].key=g;
103 guidkey[0].length=4;
104 guidkey[1].length=0;
106 wmem_tree_insert32_array(guid_to_name_tree, &guidkey[0], (char *) name);
109 /* remove a guid to name mapping */
110 void
111 guids_delete_guid(const e_guid_t *guid)
113 wmem_tree_key_t guidkey[2];
114 uint32_t g[4];
116 g[0] = guid->data1;
118 g[1] = guid->data2;
119 g[1] <<= 16;
120 g[1] |= guid->data3;
122 g[2] = guid->data4[0];
123 g[2] <<= 8;
124 g[2] |= guid->data4[1];
125 g[2] <<= 8;
126 g[2] |= guid->data4[2];
127 g[2] <<= 8;
128 g[2] |= guid->data4[3];
130 g[3] = guid->data4[4];
131 g[3] <<= 8;
132 g[3] |= guid->data4[5];
133 g[3] <<= 8;
134 g[3] |= guid->data4[6];
135 g[3] <<= 8;
136 g[3] |= guid->data4[7];
138 guidkey[0].key = g;
139 guidkey[0].length = 4;
140 guidkey[1].length = 0;
142 void *data = wmem_tree_lookup32_array(guid_to_name_tree, &guidkey[0]);
144 if (data != NULL) {
145 // This will "remove" the entry by setting its data to NULL
146 wmem_tree_insert32_array(guid_to_name_tree, &guidkey[0], NULL);
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_)
155 wmem_tree_key_t guidkey[2];
156 uint32_t g[4];
157 char *name;
158 #ifdef _WIN32
159 static char *uuid_name;
160 #endif
162 g[0]=guid->data1;
164 g[1]=guid->data2;
165 g[1]<<=16;
166 g[1]|=guid->data3;
168 g[2]=guid->data4[0];
169 g[2]<<=8;
170 g[2]|=guid->data4[1];
171 g[2]<<=8;
172 g[2]|=guid->data4[2];
173 g[2]<<=8;
174 g[2]|=guid->data4[3];
176 g[3]=guid->data4[4];
177 g[3]<<=8;
178 g[3]|=guid->data4[5];
179 g[3]<<=8;
180 g[3]|=guid->data4[6];
181 g[3]<<=8;
182 g[3]|=guid->data4[7];
184 guidkey[0].key=g;
185 guidkey[0].length=4;
186 guidkey[1].length=0;
188 if((name = (char *)wmem_tree_lookup32_array(guid_to_name_tree, &guidkey[0]))){
189 return name;
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;
199 #endif
201 return NULL;
205 void
206 guids_init(void)
208 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 */
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)
220 const char *name;
222 name=guids_get_guid_name(guid, scope);
223 if(name){
224 return name;
227 return wmem_strdup_printf(scope, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
228 guid->data1, guid->data2, guid->data3,
229 guid->data4[0], guid->data4[1],
230 guid->data4[2], guid->data4[3],
231 guid->data4[4], guid->data4[5],
232 guid->data4[6], guid->data4[7]);
235 int guid_cmp(const e_guid_t *g1, const e_guid_t *g2)
237 if (g1->data1 != g2->data1) {
238 return (g1->data1 < g2->data1) ? -1 : 1;
241 if (g1->data2 != g2->data2) {
242 return (g1->data2 < g2->data2) ? -1 : 1;
245 if (g1->data3 != g2->data3) {
246 return (g1->data3 < g2->data3) ? -1 : 1;
249 return memcmp(&g1->data4[0], &g2->data4[0], 8);
252 unsigned guid_hash(const e_guid_t *guid)
254 return g_int64_hash((const int64_t *)guid);
258 * Editor modelines - https://www.wireshark.org/tools/modelines.html
260 * Local variables:
261 * c-basic-offset: 8
262 * tab-width: 8
263 * indent-tabs-mode: t
264 * End:
266 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
267 * :indentSize=8:tabSize=8:noTabs=false: