1/* 2 * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved. 3 * The contents of this file constitute Original Code as defined in and are 4 * subject to the Apple Public Source License Version 1.2 (the 'License'). 5 * You may not use this file except in compliance with the License. Please 6 * obtain a copy of the License at http://www.apple.com/publicsource and 7 * read it before using this file. 8 * 9 * This Original Code and all software distributed under the License are 10 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 11 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 12 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 13 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please 14 * see the License for the specific language governing rights and 15 * limitations under the License. 16 */ 17 18/* 19 * PCSCDriverBundles.cpp 20 * SmartCardServices 21 */ 22 23/* 24 Creates a vector of driver bundle info structures from the hot-plug driver 25 directory. 26 27 Returns NULL on error and a pointer to an allocated HPDriver vector on 28 success. The caller must free the HPDriver with a call to HPDriversRelease(). 29 30 See http://developer.apple.com/documentation/CoreFoundation/Reference/CFArrayRef/index.html#//apple_ref/doc/uid/20001192 31 for information about CFArrayApplyFunction 32*/ 33 34#include "PCSCDriverBundles.h" 35#include <security_utilities/debugging.h> 36#include <security_utilities/cfutilities.h> 37#include <security_utilities/errors.h> 38#include <map> 39 40namespace PCSCD { 41 42static const char *kPCSCLITE_HP_DROPDIR = "/usr/libexec/SmartCardServices/drivers/"; 43static const char *kENV_PCSC_DEBUG_DRIVER = "PCSC_DEBUG_DRIVER_DIR"; // environment var 44 45DriverBundles::DriverBundles() 46{ 47 // If debugging, look in build directory 48#if !defined(NDEBUG) 49 const char *envar = kENV_PCSC_DEBUG_DRIVER; 50 if (envar) 51 if (const char *envPath = getenv(envar)) 52 { 53 // treat envPath as a classic colon-separated list of directories 54 secdebug("pathlist", "%p configuring from env(\"%s\")", this, envar); 55 while (const char *p = strchr(envPath, ':')) 56 { 57 addDirectory(string(envPath, p - envPath)); 58 envPath = p + 1; 59 } 60 addDirectory(envPath); 61 } 62#endif 63 addDirectory(kPCSCLITE_HP_DROPDIR); 64} 65 66bool DriverBundles::find(PCSCD::Device &device) const 67{ 68 // Searches for a driver bundle that matches device. If found, 69 // it sets the libpath for the device and returns true. 70 71 ProductMatchMap matchingProducts; 72 73 for (DriverBundles::const_iterator it=this->begin();it!=this->end();++it) 74 { 75 std::string name; 76 const DriverBundle *bndl = static_cast<DriverBundle *>((*it).get()); 77 if (int32_t score = bndl->matches(device, name)) 78 { 79 ProductMatchInfo *mi = new ProductMatchInfo(bndl->path(),name); 80 matchingProducts.push_back(make_pair(score, mi)); 81 } 82 } 83 84 if (matchingProducts.empty()) 85 return false; 86 87 sort(matchingProducts.begin(), matchingProducts.end()); 88 const ProductMatchInfo *mi = (*matchingProducts.rbegin()).second; 89 device.setName(mi->name()); 90 device.setPath(mi->path()); 91 // clean up 92 for (ProductMatchMap::iterator it = matchingProducts.begin();it!=matchingProducts.end();++it) 93 delete (*it).second; 94 return true; 95} 96 97} // end namespace PCSCD 98