Parse the GUID ourselves; that leaves fewer error cases to worry about,

and thus fewer places where we would need to report an error rather than
just saying "well, this name doesn't end in a GUID, so it doesn't
correspond to an interface whose friendly name we can ask for".

svn path=/trunk/; revision=46149
This commit is contained in:
Guy Harris 2012-11-23 08:10:49 +00:00
parent d2e7cfceee
commit 39fe3c0cee
1 changed files with 133 additions and 33 deletions

View File

@ -238,6 +238,54 @@ static int GetInterfaceFriendlyNameFromDeviceGuid(__in GUID *guid, __out char **
return 0;
}
static int gethexdigit(const char *p)
{
if(*p >= '0' && *p <= '9'){
return *p - '0';
}else if(*p >= 'A' && *p <= 'F'){
return *p - 'A' + 0xA;
}else if(*p >= 'a' && *p <= 'f'){
return *p - 'a' + 0xa;
}else{
return -1; /* Not a hex digit */
}
}
static gboolean get8hexdigits(const char *p, DWORD *d)
{
int digit;
DWORD val;
int i;
val = 0;
for(i = 0; i < 8; i++){
digit = gethexdigit(p++);
if(digit == -1){
return FALSE; /* Not a hex digit */
}
val = (val << 4) | digit;
}
*d = val;
return TRUE;
}
static gboolean get4hexdigits(const char *p, WORD *w)
{
int digit;
WORD val;
int i;
val = 0;
for(i = 0; i < 4; i++){
digit = gethexdigit(p++);
if(digit == -1){
return FALSE; /* Not a hex digit */
}
val = (val << 4) | digit;
}
*w = val;
return TRUE;
}
/**********************************************************************************/
/* returns the interface friendly name for a device name, if it is unable to
@ -246,6 +294,8 @@ void get_windows_interface_friendlyname(/* IN */ char *interface_devicename, /*
{
const char* guid_text;
GUID guid;
int i;
int digit1, digit2;
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "test, 1,2,3");
@ -265,41 +315,91 @@ void get_windows_interface_friendlyname(/* IN */ char *interface_devicename, /*
guid_text=interface_devicename;
}
/*** Convert the GUID text to a GUID structure */
{
/* Part 1: (presumed) ASCII guid_text to UTF-16 */
WCHAR wGuidText[39];
HRESULT hr;
int size=39; /* a guid should always been 38 unicode characters in length (+1 for null termination) */
size=MultiByteToWideChar(CP_ACP, 0, guid_text, -1, wGuidText, size);
if(size!=39){
/*
* GUID text to UTF-16 conversion failed.
* XXX - is this assuming the GUID text is in the local
* code page? If so, the error might just indicate that
* it's not in the local code page; should we assume it's
* UTF-8? If so, what if it's not *valid* UTF-8? Should
* we just silently return "no friendly name" if this
* fails?
*/
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_ERROR,
"Failed the extract guid from interface devicename, unicode convert result=%d, guid input ='%s', LastErrorCode=0x%08x.",
size, guid_text, GetLastError());
return;
/*
* If what follows is a GUID in {}, then convert it to a GUID structure
* and use that to look up the interface to get its friendly name.
*/
if(*guid_text != '{'){
return; /* Nope, not enclosed in {} */
}
guid_text++;
/* There must be 8 hex digits; if so, they go into guid.Data1 */
if(!get8hexdigits(guid_text, &guid.Data1)){
return; /* nope, not 8 hex digits */
}
guid_text += 8;
/* Now there must be a hyphen */
if(*guid_text != '-'){
return; /* Nope */
}
guid_text++;
/* There must be 4 hex digits; if so, they go into guid.Data2 */
if(!get4hexdigits(guid_text, &guid.Data2)){
return; /* nope, not 4 hex digits */
}
guid_text += 4;
/* Now there must be a hyphen */
if(*guid_text != '-'){
return; /* Nope */
}
guid_text++;
/* There must be 4 hex digits; if so, they go into guid.Data3 */
if(!get4hexdigits(guid_text, &guid.Data3)){
return; /* nope, not 4 hex digits */
}
guid_text += 4;
/* Now there must be a hyphen */
if(*guid_text != '-'){
return; /* Nope */
}
guid_text++;
/*
* There must be 4 hex digits; if so, they go into the first 2 bytes
* of guid.Data4.
*/
for(i = 0; i < 2; i++){
digit1 = gethexdigit(guid_text);
if(digit1 == -1){
return; /* Not a hex digit */
}
/* Part 2: UTF-16 GUID text to GUID structure */
hr = CLSIDFromString(wGuidText, (LPCLSID)&guid);
if (hr != S_OK){
/*
* GUID text to CLSID conversion failed; this probably
* means that there isn't a GUID in the name, in which
* case we can't get a friendly name for that name.
*
* Don't complain - this isn't an error; not all
* interface names correspond to interfaces with GUIDs.
*/
return;
guid_text++;
digit2 = gethexdigit(guid_text);
if(digit2 == -1){
return; /* Not a hex digit */
}
guid_text++;
guid.Data4[i] = (digit1 << 4)|(digit2);
}
/* Now there must be a hyphen */
if(*guid_text != '-'){
return; /* Nope */
}
guid_text++;
/*
* There must be 12 hex digits; if so,t hey go into the next 6 bytes
* of guid.Data4.
*/
for(i = 0; i < 6; i++){
digit1 = gethexdigit(guid_text);
if(digit1 == -1){
return; /* Not a hex digit */
}
guid_text++;
digit2 = gethexdigit(guid_text);
if(digit2 == -1){
return; /* Not a hex digit */
}
guid_text++;
guid.Data4[i+2] = (digit1 << 4)|(digit2);
}
/* Now there must be a closing } */
if(*guid_text != '}'){
return; /* Nope */
}
guid_text++;
/* And that must be the end of the string */
if(*guid_text != '\0'){
return; /* Nope */
}
/* guid okay, get the interface friendly name associated with the guid */