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