00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00017 #include "config.h"
00018 #include "misc.h"
00019 #include "pcscd.h"
00020
00021 #if defined(__APPLE__) && !defined(HAVE_LIBUSB)
00022 #include <CoreFoundation/CoreFoundation.h>
00023 #include <IOKit/IOCFPlugIn.h>
00024 #include <IOKit/IOKitLib.h>
00025 #include <IOKit/usb/IOUSBLib.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028
00029 #include "debuglog.h"
00030 #include "parser.h"
00031 #include "readerfactory.h"
00032 #include "winscard_msg.h"
00033 #include "utils.h"
00034 #include "hotplug.h"
00035
00036 #undef DEBUG_HOTPLUG
00037
00038
00039
00040
00041
00042 typedef struct HPDriver
00043 {
00044 UInt32 m_vendorId;
00045 UInt32 m_productId;
00046 char *m_friendlyName;
00047 char *m_libPath;
00048 } HPDriver, *HPDriverVector;
00049
00050
00051
00052
00053 typedef struct HPDevice
00054 {
00055 HPDriver *m_driver;
00056 UInt32 m_address;
00057 struct HPDevice *m_next;
00058 } HPDevice, *HPDeviceList;
00059
00060
00061
00062
00063
00064 static HPDeviceList sDeviceList = NULL;
00065
00066
00067
00068
00069
00070 static void HPDeviceAppeared(void *refCon, io_iterator_t iterator)
00071 {
00072 kern_return_t kret;
00073 io_service_t obj;
00074
00075 (void)refCon;
00076
00077 while ((obj = IOIteratorNext(iterator)))
00078 kret = IOObjectRelease(obj);
00079
00080 HPSearchHotPluggables();
00081 }
00082
00083
00084
00085
00086
00087 static void HPDeviceDisappeared(void *refCon, io_iterator_t iterator)
00088 {
00089 kern_return_t kret;
00090 io_service_t obj;
00091
00092 (void)refCon;
00093
00094 while ((obj = IOIteratorNext(iterator)))
00095 kret = IOObjectRelease(obj);
00096
00097 HPSearchHotPluggables();
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 static HPDriverVector HPDriversGetFromDirectory(const char *driverBundlePath)
00110 {
00111 int i;
00112 #ifdef DEBUG_HOTPLUG
00113 Log2(PCSC_LOG_DEBUG, "Entering HPDriversGetFromDirectory: %s",
00114 driverBundlePath);
00115 #endif
00116
00117 int readersNumber = 0;
00118 HPDriverVector bundleVector = NULL;
00119 CFArrayRef bundleArray;
00120 CFStringRef driverBundlePathString =
00121 CFStringCreateWithCString(kCFAllocatorDefault,
00122 driverBundlePath,
00123 kCFStringEncodingMacRoman);
00124 CFURLRef pluginUrl = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
00125 driverBundlePathString,
00126 kCFURLPOSIXPathStyle, TRUE);
00127
00128 CFRelease(driverBundlePathString);
00129 if (!pluginUrl)
00130 {
00131 Log1(PCSC_LOG_ERROR, "error getting plugin directory URL");
00132 return NULL;
00133 }
00134 bundleArray = CFBundleCreateBundlesFromDirectory(kCFAllocatorDefault,
00135 pluginUrl, NULL);
00136 if (!bundleArray)
00137 {
00138 Log1(PCSC_LOG_ERROR, "error getting plugin directory bundles");
00139 return NULL;
00140 }
00141 CFRelease(pluginUrl);
00142
00143 size_t bundleArraySize = CFArrayGetCount(bundleArray);
00144
00145
00146 for (i = 0; i < bundleArraySize; i++)
00147 {
00148 CFBundleRef currBundle =
00149 (CFBundleRef) CFArrayGetValueAtIndex(bundleArray, i);
00150 CFDictionaryRef dict = CFBundleGetInfoDictionary(currBundle);
00151
00152 const void * blobValue = CFDictionaryGetValue(dict,
00153 CFSTR(PCSCLITE_HP_MANUKEY_NAME));
00154
00155 if (!blobValue)
00156 {
00157 Log1(PCSC_LOG_ERROR, "error getting vendor ID from bundle");
00158 return NULL;
00159 }
00160
00161 if (CFGetTypeID(blobValue) == CFArrayGetTypeID())
00162 {
00163
00164 CFArrayRef propertyArray = blobValue;
00165 readersNumber += CFArrayGetCount(propertyArray);
00166 }
00167 else
00168
00169 readersNumber++;
00170 }
00171 #ifdef DEBUG_HOTPLUG
00172 Log2(PCSC_LOG_DEBUG, "Total of %d readers supported", readersNumber);
00173 #endif
00174
00175
00176
00177
00178 readersNumber++;
00179
00180 bundleVector = (HPDriver *) calloc(readersNumber, sizeof(HPDriver));
00181 if (!bundleVector)
00182 {
00183 Log1(PCSC_LOG_ERROR, "memory allocation failure");
00184 return NULL;
00185 }
00186
00187 HPDriver *driverBundle = bundleVector;
00188 for (i = 0; i < bundleArraySize; i++)
00189 {
00190 CFBundleRef currBundle =
00191 (CFBundleRef) CFArrayGetValueAtIndex(bundleArray, i);
00192 CFDictionaryRef dict = CFBundleGetInfoDictionary(currBundle);
00193
00194 CFURLRef bundleUrl = CFBundleCopyBundleURL(currBundle);
00195 CFStringRef bundlePath = CFURLCopyPath(bundleUrl);
00196
00197 driverBundle->m_libPath = strdup(CFStringGetCStringPtr(bundlePath,
00198 CFStringGetSystemEncoding()));
00199
00200 const void * blobValue = CFDictionaryGetValue(dict,
00201 CFSTR(PCSCLITE_HP_MANUKEY_NAME));
00202
00203 if (!blobValue)
00204 {
00205 Log1(PCSC_LOG_ERROR, "error getting vendor ID from bundle");
00206 return bundleVector;
00207 }
00208
00209 if (CFGetTypeID(blobValue) == CFArrayGetTypeID())
00210 {
00211 CFArrayRef vendorArray = blobValue;
00212 CFArrayRef productArray;
00213 CFArrayRef friendlyNameArray;
00214 char *libPath = driverBundle->m_libPath;
00215
00216 #ifdef DEBUG_HOTPLUG
00217 Log2(PCSC_LOG_DEBUG, "Driver with aliases: %s", libPath);
00218 #endif
00219
00220 productArray = CFDictionaryGetValue(dict,
00221 CFSTR(PCSCLITE_HP_PRODKEY_NAME));
00222 if (!productArray)
00223 {
00224 Log1(PCSC_LOG_ERROR, "error getting product ID from bundle");
00225 return bundleVector;
00226 }
00227
00228
00229 friendlyNameArray = CFDictionaryGetValue(dict,
00230 CFSTR(PCSCLITE_HP_NAMEKEY_NAME));
00231 if (!friendlyNameArray)
00232 {
00233 Log1(PCSC_LOG_ERROR, "error getting product ID from bundle");
00234 return bundleVector;
00235 }
00236
00237 int reader_nb = CFArrayGetCount(vendorArray);
00238
00239 if (reader_nb != CFArrayGetCount(productArray))
00240 {
00241 Log3(PCSC_LOG_ERROR,
00242 "Malformed Info.plist: %d vendors and %d products",
00243 reader_nb, CFArrayGetCount(productArray));
00244 return bundleVector;
00245 }
00246
00247 if (reader_nb != CFArrayGetCount(friendlyNameArray))
00248 {
00249 Log3(PCSC_LOG_ERROR,
00250 "Malformed Info.plist: %d vendors and %d friendlynames",
00251 reader_nb, CFArrayGetCount(friendlyNameArray));
00252 return bundleVector;
00253 }
00254
00255 int j;
00256 for (j=0; j<reader_nb; j++)
00257 {
00258 CFStringRef strValue = CFArrayGetValueAtIndex(vendorArray, j);
00259
00260 driverBundle->m_vendorId = strtoul(CFStringGetCStringPtr(strValue,
00261 CFStringGetSystemEncoding()), NULL, 16);
00262
00263 strValue = CFArrayGetValueAtIndex(productArray, j);
00264 driverBundle->m_productId = strtoul(CFStringGetCStringPtr(strValue,
00265 CFStringGetSystemEncoding()), NULL, 16);
00266
00267 strValue = CFArrayGetValueAtIndex(friendlyNameArray, j);
00268 const char *cstr = CFStringGetCStringPtr(strValue,
00269 CFStringGetSystemEncoding());
00270
00271 driverBundle->m_friendlyName = strdup(cstr);
00272 if (!driverBundle->m_libPath)
00273 driverBundle->m_libPath = strdup(libPath);
00274
00275 #ifdef DEBUG_HOTPLUG
00276 Log2(PCSC_LOG_DEBUG, "VendorID: 0x%04X",
00277 driverBundle->m_vendorId);
00278 Log2(PCSC_LOG_DEBUG, "ProductID: 0x%04X",
00279 driverBundle->m_productId);
00280 Log2(PCSC_LOG_DEBUG, "Friendly name: %s",
00281 driverBundle->m_friendlyName);
00282 Log2(PCSC_LOG_DEBUG, "Driver: %s", driverBundle->m_libPath);
00283 #endif
00284
00285
00286 driverBundle++;
00287 }
00288 }
00289 else
00290 {
00291 CFStringRef strValue = blobValue;
00292
00293 #ifdef DEBUG_HOTPLUG
00294 Log3(PCSC_LOG_DEBUG, "Driver without alias: %s",
00295 driverBundle, driverBundle->m_libPath);
00296 #endif
00297
00298 driverBundle->m_vendorId = strtoul(CFStringGetCStringPtr(strValue,
00299 CFStringGetSystemEncoding()), NULL, 16);
00300
00301 strValue = (CFStringRef) CFDictionaryGetValue(dict,
00302 CFSTR(PCSCLITE_HP_PRODKEY_NAME));
00303 if (!strValue)
00304 {
00305 Log1(PCSC_LOG_ERROR, "error getting product ID from bundle");
00306 return bundleVector;
00307 }
00308 driverBundle->m_productId = strtoul(CFStringGetCStringPtr(strValue,
00309 CFStringGetSystemEncoding()), NULL, 16);
00310
00311 strValue = (CFStringRef) CFDictionaryGetValue(dict,
00312 CFSTR(PCSCLITE_HP_NAMEKEY_NAME));
00313 if (!strValue)
00314 {
00315 Log1(PCSC_LOG_ERROR, "error getting product friendly name from bundle");
00316 driverBundle->m_friendlyName = strdup("unnamed device");
00317 }
00318 else
00319 {
00320 const char *cstr = CFStringGetCStringPtr(strValue,
00321 CFStringGetSystemEncoding());
00322
00323 driverBundle->m_friendlyName = strdup(cstr);
00324 }
00325 #ifdef DEBUG_HOTPLUG
00326 Log2(PCSC_LOG_DEBUG, "VendorID: 0x%04X", driverBundle->m_vendorId);
00327 Log2(PCSC_LOG_DEBUG, "ProductID: 0x%04X", driverBundle->m_productId);
00328 Log2(PCSC_LOG_DEBUG, "Friendly name: %s", driverBundle->m_friendlyName);
00329 Log2(PCSC_LOG_DEBUG, "Driver: %s", driverBundle->m_libPath);
00330 #endif
00331
00332
00333 driverBundle++;
00334 }
00335 }
00336 CFRelease(bundleArray);
00337 return bundleVector;
00338 }
00339
00340
00341
00342
00343 static HPDriver *HPDriverCopy(HPDriver * rhs)
00344 {
00345 if (!rhs)
00346 return NULL;
00347
00348 HPDriver *newDriverBundle = (HPDriver *) calloc(1, sizeof(HPDriver));
00349
00350 if (!newDriverBundle)
00351 return NULL;
00352
00353 newDriverBundle->m_vendorId = rhs->m_vendorId;
00354 newDriverBundle->m_productId = rhs->m_productId;
00355 newDriverBundle->m_friendlyName = strdup(rhs->m_friendlyName);
00356 newDriverBundle->m_libPath = strdup(rhs->m_libPath);
00357
00358 return newDriverBundle;
00359 }
00360
00361
00362
00363
00364 static void HPDriverRelease(HPDriver * driverBundle)
00365 {
00366 if (driverBundle)
00367 {
00368 free(driverBundle->m_friendlyName);
00369 free(driverBundle->m_libPath);
00370 }
00371 }
00372
00373
00374
00375
00376 static void HPDriverVectorRelease(HPDriverVector driverBundleVector)
00377 {
00378 if (driverBundleVector)
00379 {
00380 HPDriver *b;
00381
00382 for (b = driverBundleVector; b->m_vendorId; ++b)
00383 HPDriverRelease(b);
00384
00385 free(driverBundleVector);
00386 }
00387 }
00388
00389
00390
00391
00392 static HPDeviceList
00393 HPDeviceListInsert(HPDeviceList list, HPDriver * bundle, UInt32 address)
00394 {
00395 HPDevice *newReader = (HPDevice *) calloc(1, sizeof(HPDevice));
00396
00397 if (!newReader)
00398 {
00399 Log1(PCSC_LOG_ERROR, "memory allocation failure");
00400 return list;
00401 }
00402
00403 newReader->m_driver = HPDriverCopy(bundle);
00404 newReader->m_address = address;
00405 newReader->m_next = list;
00406
00407 return newReader;
00408 }
00409
00410
00411
00412
00413 static void HPDeviceListRelease(HPDeviceList list)
00414 {
00415 HPDevice *p;
00416
00417 for (p = list; p; p = p->m_next)
00418 HPDriverRelease(p->m_driver);
00419 }
00420
00421
00422
00423
00424 static int HPDeviceEquals(HPDevice * a, HPDevice * b)
00425 {
00426 return (a->m_driver->m_vendorId == b->m_driver->m_vendorId)
00427 && (a->m_driver->m_productId == b->m_driver->m_productId)
00428 && (a->m_address == b->m_address);
00429 }
00430
00431
00432
00433
00434
00435 static int
00436 HPDriversMatchUSBDevices(HPDriverVector driverBundle,
00437 HPDeviceList * readerList)
00438 {
00439 CFDictionaryRef usbMatch = IOServiceMatching("IOUSBDevice");
00440
00441 if (0 == usbMatch)
00442 {
00443 Log1(PCSC_LOG_ERROR,
00444 "error getting USB match from IOServiceMatching()");
00445 return 1;
00446 }
00447
00448 io_iterator_t usbIter;
00449 kern_return_t kret = IOServiceGetMatchingServices(kIOMasterPortDefault,
00450 usbMatch, &usbIter);
00451
00452 if (kret != 0)
00453 {
00454 Log1(PCSC_LOG_ERROR,
00455 "error getting iterator from IOServiceGetMatchingServices()");
00456 return 1;
00457 }
00458
00459 IOIteratorReset(usbIter);
00460 io_object_t usbDevice = 0;
00461
00462 while ((usbDevice = IOIteratorNext(usbIter)))
00463 {
00464 char namebuf[1024];
00465
00466 kret = IORegistryEntryGetName(usbDevice, namebuf);
00467 if (kret != 0)
00468 {
00469 Log1(PCSC_LOG_ERROR,
00470 "error getting device name from IORegistryEntryGetName()");
00471 return 1;
00472 }
00473
00474 IOCFPlugInInterface **iodev;
00475 SInt32 score;
00476
00477 kret = IOCreatePlugInInterfaceForService(usbDevice,
00478 kIOUSBDeviceUserClientTypeID,
00479 kIOCFPlugInInterfaceID, &iodev, &score);
00480 if (kret != 0)
00481 {
00482 Log1(PCSC_LOG_ERROR, "error getting plugin interface from IOCreatePlugInInterfaceForService()");
00483 return 1;
00484 }
00485 IOObjectRelease(usbDevice);
00486
00487 IOUSBDeviceInterface **usbdev;
00488 HRESULT hres = (*iodev)->QueryInterface(iodev,
00489 CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
00490 (LPVOID *) & usbdev);
00491
00492 (*iodev)->Release(iodev);
00493 if (hres)
00494 {
00495 Log1(PCSC_LOG_ERROR,
00496 "error querying interface in QueryInterface()");
00497 return 1;
00498 }
00499
00500 UInt16 vendorId = 0;
00501 UInt16 productId = 0;
00502 UInt32 usbAddress = 0;
00503
00504 kret = (*usbdev)->GetDeviceVendor(usbdev, &vendorId);
00505 kret = (*usbdev)->GetDeviceProduct(usbdev, &productId);
00506 kret = (*usbdev)->GetLocationID(usbdev, &usbAddress);
00507 (*usbdev)->Release(usbdev);
00508
00509 HPDriver *driver;
00510 for (driver = driverBundle; driver->m_vendorId; ++driver)
00511 {
00512 if ((driver->m_vendorId == vendorId)
00513 && (driver->m_productId == productId))
00514 {
00515 *readerList =
00516 HPDeviceListInsert(*readerList, driver, usbAddress);
00517 }
00518 }
00519 }
00520
00521 IOObjectRelease(usbIter);
00522 return 0;
00523 }
00524
00525
00526
00527
00528
00529 static int
00530 HPDriversMatchPCCardDevices(HPDriver * driverBundle,
00531 HPDeviceList * readerList)
00532 {
00533 CFDictionaryRef pccMatch = IOServiceMatching("IOPCCard16Device");
00534
00535 if (pccMatch == NULL)
00536 {
00537 Log1(PCSC_LOG_ERROR,
00538 "error getting PCCard match from IOServiceMatching()");
00539 return 1;
00540 }
00541
00542 io_iterator_t pccIter;
00543 kern_return_t kret =
00544 IOServiceGetMatchingServices(kIOMasterPortDefault, pccMatch,
00545 &pccIter);
00546 if (kret != 0)
00547 {
00548 Log1(PCSC_LOG_ERROR,
00549 "error getting iterator from IOServiceGetMatchingServices()");
00550 return 1;
00551 }
00552
00553 IOIteratorReset(pccIter);
00554 io_object_t pccDevice = 0;
00555
00556 while ((pccDevice = IOIteratorNext(pccIter)))
00557 {
00558 char namebuf[1024];
00559
00560 kret = IORegistryEntryGetName(pccDevice, namebuf);
00561 if (kret != 0)
00562 {
00563 Log1(PCSC_LOG_ERROR, "error getting plugin interface from IOCreatePlugInInterfaceForService()");
00564 return 1;
00565 }
00566 UInt32 vendorId = 0;
00567 UInt32 productId = 0;
00568 UInt32 pccAddress = 0;
00569 CFTypeRef valueRef =
00570 IORegistryEntryCreateCFProperty(pccDevice, CFSTR("VendorID"),
00571 kCFAllocatorDefault, 0);
00572
00573 if (!valueRef)
00574 {
00575 Log1(PCSC_LOG_ERROR, "error getting vendor");
00576 }
00577 else
00578 {
00579 CFNumberGetValue((CFNumberRef) valueRef, kCFNumberSInt32Type,
00580 &vendorId);
00581 }
00582 valueRef =
00583 IORegistryEntryCreateCFProperty(pccDevice, CFSTR("DeviceID"),
00584 kCFAllocatorDefault, 0);
00585 if (!valueRef)
00586 {
00587 Log1(PCSC_LOG_ERROR, "error getting device");
00588 }
00589 else
00590 {
00591 CFNumberGetValue((CFNumberRef) valueRef, kCFNumberSInt32Type,
00592 &productId);
00593 }
00594 valueRef =
00595 IORegistryEntryCreateCFProperty(pccDevice, CFSTR("SocketNumber"),
00596 kCFAllocatorDefault, 0);
00597 if (!valueRef)
00598 {
00599 Log1(PCSC_LOG_ERROR, "error getting PC Card socket");
00600 }
00601 else
00602 {
00603 CFNumberGetValue((CFNumberRef) valueRef, kCFNumberSInt32Type,
00604 &pccAddress);
00605 }
00606 HPDriver *driver = driverBundle;
00607
00608 for (; driver->m_vendorId; ++driver)
00609 {
00610 if ((driver->m_vendorId == vendorId)
00611 && (driver->m_productId == productId))
00612 {
00613 *readerList =
00614 HPDeviceListInsert(*readerList, driver, pccAddress);
00615 }
00616 }
00617 }
00618 IOObjectRelease(pccIter);
00619 return 0;
00620 }
00621
00622
00623 static void HPEstablishUSBNotification(void)
00624 {
00625 io_iterator_t deviceAddedIterator;
00626 io_iterator_t deviceRemovedIterator;
00627 CFMutableDictionaryRef matchingDictionary;
00628 IONotificationPortRef notificationPort;
00629 IOReturn kret;
00630
00631 notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
00632 CFRunLoopAddSource(CFRunLoopGetCurrent(),
00633 IONotificationPortGetRunLoopSource(notificationPort),
00634 kCFRunLoopDefaultMode);
00635
00636 matchingDictionary = IOServiceMatching("IOUSBDevice");
00637 if (!matchingDictionary)
00638 {
00639 Log1(PCSC_LOG_ERROR, "IOServiceMatching() failed");
00640 }
00641 matchingDictionary =
00642 (CFMutableDictionaryRef) CFRetain(matchingDictionary);
00643
00644 kret = IOServiceAddMatchingNotification(notificationPort,
00645 kIOMatchedNotification,
00646 matchingDictionary, HPDeviceAppeared, NULL, &deviceAddedIterator);
00647 if (kret)
00648 {
00649 Log2(PCSC_LOG_ERROR,
00650 "IOServiceAddMatchingNotification()-1 failed with code %d", kret);
00651 }
00652 HPDeviceAppeared(NULL, deviceAddedIterator);
00653
00654 kret = IOServiceAddMatchingNotification(notificationPort,
00655 kIOTerminatedNotification,
00656 matchingDictionary,
00657 HPDeviceDisappeared, NULL, &deviceRemovedIterator);
00658 if (kret)
00659 {
00660 Log2(PCSC_LOG_ERROR,
00661 "IOServiceAddMatchingNotification()-2 failed with code %d", kret);
00662 }
00663 HPDeviceDisappeared(NULL, deviceRemovedIterator);
00664 }
00665
00666 static void HPEstablishPCCardNotification(void)
00667 {
00668 io_iterator_t deviceAddedIterator;
00669 io_iterator_t deviceRemovedIterator;
00670 CFMutableDictionaryRef matchingDictionary;
00671 IONotificationPortRef notificationPort;
00672 IOReturn kret;
00673
00674 notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
00675 CFRunLoopAddSource(CFRunLoopGetCurrent(),
00676 IONotificationPortGetRunLoopSource(notificationPort),
00677 kCFRunLoopDefaultMode);
00678
00679 matchingDictionary = IOServiceMatching("IOPCCard16Device");
00680 if (!matchingDictionary)
00681 {
00682 Log1(PCSC_LOG_ERROR, "IOServiceMatching() failed");
00683 }
00684 matchingDictionary =
00685 (CFMutableDictionaryRef) CFRetain(matchingDictionary);
00686
00687 kret = IOServiceAddMatchingNotification(notificationPort,
00688 kIOMatchedNotification,
00689 matchingDictionary, HPDeviceAppeared, NULL, &deviceAddedIterator);
00690 if (kret)
00691 {
00692 Log2(PCSC_LOG_ERROR,
00693 "IOServiceAddMatchingNotification()-1 failed with code %d", kret);
00694 }
00695 HPDeviceAppeared(NULL, deviceAddedIterator);
00696
00697 kret = IOServiceAddMatchingNotification(notificationPort,
00698 kIOTerminatedNotification,
00699 matchingDictionary,
00700 HPDeviceDisappeared, NULL, &deviceRemovedIterator);
00701 if (kret)
00702 {
00703 Log2(PCSC_LOG_ERROR,
00704 "IOServiceAddMatchingNotification()-2 failed with code %d", kret);
00705 }
00706 HPDeviceDisappeared(NULL, deviceRemovedIterator);
00707 }
00708
00709
00710
00711
00712 static void HPDeviceNotificationThread(void)
00713 {
00714 HPEstablishUSBNotification();
00715 HPEstablishPCCardNotification();
00716 CFRunLoopRun();
00717 }
00718
00719
00720
00721
00722
00723
00724 LONG HPSearchHotPluggables(void)
00725 {
00726 HPDriver *drivers = HPDriversGetFromDirectory(PCSCLITE_HP_DROPDIR);
00727
00728 if (!drivers)
00729 return 1;
00730
00731 HPDeviceList devices = NULL;
00732
00733 if (HPDriversMatchUSBDevices(drivers, &devices))
00734 return -1;
00735
00736 if (HPDriversMatchPCCardDevices(drivers, &devices))
00737 return -1;
00738
00739 HPDevice *a;
00740
00741 for (a = devices; a; a = a->m_next)
00742 {
00743 int found = FALSE;
00744 HPDevice *b;
00745
00746 for (b = sDeviceList; b; b = b->m_next)
00747 {
00748 if (HPDeviceEquals(a, b))
00749 {
00750 found = TRUE;
00751 break;
00752 }
00753 }
00754 if (!found)
00755 {
00756 char deviceName[MAX_DEVICENAME];
00757
00758
00759
00760
00761 snprintf(deviceName, sizeof(deviceName), "usb:%04x/%04x",
00762 (unsigned int)a->m_driver->m_vendorId,
00763 (unsigned int)a->m_driver->m_productId);
00764 deviceName[sizeof(deviceName)-1] = '\0';
00765
00766 RFAddReader(a->m_driver->m_friendlyName,
00767 PCSCLITE_HP_BASE_PORT + a->m_address, a->m_driver->m_libPath,
00768 deviceName);
00769 }
00770 }
00771
00772 for (a = sDeviceList; a; a = a->m_next)
00773 {
00774 int found = FALSE;
00775 HPDevice *b;
00776
00777 for (b = devices; b; b = b->m_next)
00778 {
00779 if (HPDeviceEquals(a, b))
00780 {
00781 found = TRUE;
00782 break;
00783 }
00784 }
00785 if (!found)
00786 {
00787 RFRemoveReader(a->m_driver->m_friendlyName,
00788 PCSCLITE_HP_BASE_PORT + a->m_address);
00789 }
00790 }
00791
00792 HPDeviceListRelease(sDeviceList);
00793 sDeviceList = devices;
00794 HPDriverVectorRelease(drivers);
00795
00796 return 0;
00797 }
00798
00799
00800 pthread_t sHotplugWatcherThread;
00801
00802
00803
00804
00805 ULONG HPRegisterForHotplugEvents(void)
00806 {
00807 ThreadCreate(&sHotplugWatcherThread,
00808 THREAD_ATTR_DEFAULT,
00809 (PCSCLITE_THREAD_FUNCTION( )) HPDeviceNotificationThread, NULL);
00810
00811 return 0;
00812 }
00813
00814 LONG HPStopHotPluggables(void)
00815 {
00816 return 0;
00817 }
00818
00819 void HPReCheckSerialReaders(void)
00820 {
00821 }
00822
00823 #endif
00824