IOHIDFamilyPrivate.cpp [plain text]
#include "IOHIDFamilyPrivate.h"
#define kHIDTransport1ScoreIncrement 1000
#define kHIDTransport2ScoreIncrement 2000
#define kHIDDeviceUsageScoreBase 1100
#define kHIDDeviceUsageScoreIncrement 100
#define kHIDVendor1ScoreIncrement 5000
#define kHIDVendor2ScoreIncrement 1000
#define kHIDVendor3ScoreIncrement 100
bool CompareProperty( IOService * owner, OSDictionary * matching, const char * key, SInt32 * score, SInt32 increment)
{
OSObject * value;
OSObject * property;
bool matches = true;
value = matching->getObject( key );
if( value)
{
property = owner->copyProperty( key );
if ( property )
{
matches = value->isEqualTo( property );
if (matches && score)
*score += increment;
property->release();
}
else
matches = false;
}
return matches;
}
bool CompareDeviceUsage( IOService * owner, OSDictionary * matching, SInt32 * score, SInt32 increment)
{
OSObject * usage;
OSObject * usagePage;
OSArray * functions;
OSDictionary * pair;
bool matches = true;
int count;
usage = matching->getObject( kIOHIDDeviceUsageKey );
usagePage = matching->getObject( kIOHIDDeviceUsagePageKey );
functions = OSDynamicCast(OSArray, owner->copyProperty( kIOHIDDeviceUsagePairsKey ));
if ( functions )
{
if ( usagePage || usage )
{
count = functions->getCount();
for (int i=0; i<count; i++)
{
if ( !(pair = (OSDictionary *)functions->getObject(i)) )
continue;
if ( !usagePage ||
!(matches = usagePage->isEqualTo(pair->getObject(kIOHIDDeviceUsagePageKey))) )
continue;
if ( score && !usage )
{
*score += increment / 2;
break;
}
if ( !usage ||
!(matches = usage->isEqualTo(pair->getObject(kIOHIDDeviceUsageKey))) )
continue;
if ( score )
*score += increment;
break;
}
}
functions->release();
} else {
matches = false;
}
return matches;
}
bool CompareDeviceUsagePairs( IOService * owner, OSDictionary * matching, SInt32 * score, SInt32 increment)
{
OSArray * pairArray;
OSDictionary * pair;
bool matches = true;
int count;
pairArray = OSDynamicCast(OSArray, matching->getObject( kIOHIDDeviceUsagePairsKey ));
if (pairArray)
{
count = pairArray->getCount();
for (int i=0; i<count; i++)
{
if ( !(pair = OSDynamicCast(OSDictionary,pairArray->getObject(i))) )
continue;
if ( !(matches = CompareDeviceUsage(owner, pair, score, increment)) )
continue;
break;
}
}
return matches;
}
bool MatchPropertyTable(IOService * owner, OSDictionary * table, SInt32 * score)
{
bool match = true;
SInt32 pUScore = 0;
SInt32 pUPScore = 0;
SInt32 useScore = 0;
SInt32 trans1Score = 0;
SInt32 trans2Score = 0;
SInt32 ven1Score = 0;
SInt32 ven2Score = 0;
SInt32 ven3Score = 0;
if (!CompareProperty(owner, table, kIOHIDTransportKey, &trans1Score, kHIDTransport1ScoreIncrement) ||
!CompareProperty(owner, table, kIOHIDLocationIDKey, &trans2Score, kHIDTransport2ScoreIncrement) ||
!CompareProperty(owner, table, kIOHIDVendorIDKey, &ven1Score, kHIDVendor1ScoreIncrement) ||
!CompareProperty(owner, table, kIOHIDProductIDKey, &ven2Score, kHIDVendor2ScoreIncrement) ||
!CompareProperty(owner, table, kIOHIDVersionNumberKey, &ven3Score, kHIDVendor3ScoreIncrement) ||
!CompareProperty(owner, table, kIOHIDManufacturerKey, &ven3Score, kHIDVendor3ScoreIncrement) ||
!CompareProperty(owner, table, kIOHIDSerialNumberKey, &ven3Score, kHIDVendor3ScoreIncrement) ||
!CompareProperty(owner, table, kIOHIDPrimaryUsagePageKey, &pUPScore, kHIDDeviceUsageScoreBase) ||
!CompareProperty(owner, table, kIOHIDPrimaryUsageKey, &pUScore, kHIDDeviceUsageScoreIncrement) ||
!CompareDeviceUsagePairs(owner, table, &useScore, kHIDDeviceUsageScoreIncrement) ||
!CompareDeviceUsage(owner, table, &useScore, kHIDDeviceUsageScoreIncrement) ||
!CompareProperty(owner, table, "BootProtocol", score) ||
(table->getObject("HIDDefaultBehavior") && !owner->getProperty("HIDDefaultBehavior")))
{
if (score)
*score = 0;
match = false;
}
else if ( score )
{
if ( trans1Score > 0 )
*score += trans1Score + trans2Score;
if ( ven1Score > 0 )
*score += ven1Score + ven2Score + ven3Score;
if ( useScore > 0 )
*score += useScore + kHIDDeviceUsageScoreBase;
else if ( pUPScore > 0 )
*score += pUPScore + pUScore;
}
return match;
}