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