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
17 #include <epan/epan.h>
18 #include <wsutil/unicode-utils.h>
19 #include <epan/wmem_scopes.h>
20 #include "guid-utils.h"
28 static wmem_tree_t
*guid_to_name_tree
;
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 */
35 ResolveWin32UUID(e_guid_t if_id
, char *uuid_name
, int uuid_name_max_len
)
39 DWORD uuid_max_size
= MAX_PATH
;
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){
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
));
59 wmem_free(NULL
, reg_uuid_name
);
60 wmem_free(NULL
, reg_uuid_str
);
61 return (int) strlen(uuid_name
);
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! */
73 /* store a guid to name mapping */
75 guids_add_guid(const e_guid_t
*guid
, const char *name
)
77 wmem_tree_key_t guidkey
[2];
100 g
[3]|=guid
->data4
[7];
106 wmem_tree_insert32_array(guid_to_name_tree
, &guidkey
[0], (char *) name
);
109 /* remove a guid to name mapping */
111 guids_delete_guid(const e_guid_t
*guid
)
113 wmem_tree_key_t guidkey
[2];
122 g
[2] = guid
->data4
[0];
124 g
[2] |= guid
->data4
[1];
126 g
[2] |= guid
->data4
[2];
128 g
[2] |= guid
->data4
[3];
130 g
[3] = guid
->data4
[4];
132 g
[3] |= guid
->data4
[5];
134 g
[3] |= guid
->data4
[6];
136 g
[3] |= guid
->data4
[7];
139 guidkey
[0].length
= 4;
140 guidkey
[1].length
= 0;
142 void *data
= wmem_tree_lookup32_array(guid_to_name_tree
, &guidkey
[0]);
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 */
153 guids_get_guid_name(const e_guid_t
*guid
, wmem_allocator_t
*scope _U_
)
155 wmem_tree_key_t guidkey
[2];
159 static char *uuid_name
;
170 g
[2]|=guid
->data4
[1];
172 g
[2]|=guid
->data4
[2];
174 g
[2]|=guid
->data4
[3];
178 g
[3]|=guid
->data4
[5];
180 g
[3]|=guid
->data4
[6];
182 g
[3]|=guid
->data4
[7];
188 if((name
= (char *)wmem_tree_lookup32_array(guid_to_name_tree
, &guidkey
[0]))){
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)) {
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) */
218 guids_resolve_guid_to_str(const e_guid_t
*guid
, wmem_allocator_t
*scope
)
222 name
=guids_get_guid_name(guid
, scope
);
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
263 * indent-tabs-mode: t
266 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
267 * :indentSize=8:tabSize=8:noTabs=false: