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:
parent
d2e7cfceee
commit
39fe3c0cee
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue