/*
- * "$Id$"
+ * USB backend for macOS.
*
- * Copyright 2005-2015 Apple Inc. All rights reserved.
+ * Copyright © 2005-2021 Apple Inc. All rights reserved.
*
* IMPORTANT: This Apple software is supplied to you by Apple Computer,
* Inc. ("Apple") in consideration of your agreement to the following
} classdriver_t;
-typedef Boolean (*iterator_callback_t)(void *refcon, io_service_t obj, CFStringRef deviceIDString, UInt32 deviceLocation, UInt8 interfaceNum, UInt8 alternateSetting);
+typedef Boolean (*iterator_callback_t)(io_service_t obj, printer_interface_t printerIntf, void *refcon);
typedef struct iterator_reference_s /**** Iterator reference data */
{
UInt32 location;
UInt8 interfaceNum;
UInt8 alternateSetting;
+ UInt8 interfaceProtocol;
CFRunLoopTimerRef status_timer;
* Local functions...
*/
-static Boolean find_device_cb(void *refcon, io_service_t obj, CFStringRef deviceIDString, UInt32 deviceLocation, UInt8 interfaceNum, UInt8 alternateSetting);
-static Boolean list_device_cb(void *refcon, io_service_t obj, CFStringRef deviceIDString, UInt32 deviceLocation, UInt8 interfaceNum, UInt8 alternateSetting);
+static Boolean list_device_cb(io_service_t obj, printer_interface_t printerIntf, void *refcon);
+static Boolean find_device_cb(io_service_t obj, printer_interface_t printerIntf, void *refcon);
static CFStringRef cfstr_create_trim(const char *cstr);
static CFStringRef copy_value_for_key(CFStringRef deviceID, CFStringRef *keys);
static void setup_cfLanguage(void);
static void soft_reset(void);
static void status_timer_cb(CFRunLoopTimerRef timer, void *info);
-static void log_usb_class_driver(int is_64bit);
#define IS_64BIT 1
#define IS_NOT_64BIT 0
-#if defined(__i386__) || defined(__x86_64__)
+#if defined(__arm64e__)
static pid_t child_pid; /* Child PID */
-static void run_legacy_backend(int argc, char *argv[], int fd) __attribute__((noreturn)); /* Starts child backend process running as a ppc executable */
-#endif /* __i386__ || __x86_64__ */
-static void sigterm_handler(int sig); /* SIGTERM handler */
-static void sigquit_handler(int sig, siginfo_t *si, void *unused) __attribute__((noreturn));
+static void run_legacy_backend(int argc, char *argv[], int fd) _CUPS_NORETURN; /* Starts child backend process running as a x86_64 executable */
+static void sigterm_handler(int sig); /* SIGTERM handler */
+#endif /* __arm64e__ */
+static void sigquit_handler(int sig, siginfo_t *si, void *unused) _CUPS_NORETURN;
#ifdef PARSE_PS_ERRORS
static const char *next_line (const char *buffer);
#endif /* PARSE_PS_ERRORS */
static printer_interface_t usb_printer_interface_interface(io_service_t usbClass);
-static IOUSBDeviceInterface **usb_device_interface_for_device(io_service_t usbDevice);
+
static CFStringRef copy_printer_interface_deviceid(printer_interface_t printer, UInt8 alternateSetting);
static CFStringRef copy_printer_interface_indexed_description(printer_interface_t printer, UInt8 index, UInt16 language);
static CFStringRef deviceIDCopyManufacturer(CFStringRef deviceID);
g.printer_obj = 0x0;
g.classdriver = 0x0;
}
-
fprintf(stderr, "DEBUG: Looking for '%s %s'\n", hostname, resource);
- iterate_printers(find_device_cb, NULL);
+ do
+ {
+ iterate_printers(find_device_cb, NULL);
+ if (g.printer_obj != 0x0)
+ break;
+
+ _cupsLangPrintFilter(stderr, "INFO", _("Waiting for printer to become available."));
+ sleep(5);
+ } while (true);
fputs("DEBUG: Opening connection\n", stderr);
status = registry_open(&driverBundlePath);
-#if defined(__i386__) || defined(__x86_64__)
+#if defined(__arm64e__)
/*
* If we were unable to load the class drivers for this printer it's
- * probably because they're ppc or i386. In this case try to run this
- * backend as i386 or ppc executables so we can use them...
+ * probably because they're x86_64 (or older). In this case try to run this
+ * backend as x86_64 so we can use them...
*/
if (status == -2)
{
run_legacy_backend(argc, argv, print_fd);
/* Never returns here */
}
-#endif /* __i386__ || __x86_64__ */
+#endif /* __arm64e__ */
if (status == -2)
{
return (CUPS_BACKEND_STOP);
}
-#ifdef __x86_64__
- if (status == noErr && driverBundlePath != NULL && CFStringCompare(driverBundlePath, kUSBGenericTOPrinterClassDriver, 0) != kCFCompareEqualTo)
- log_usb_class_driver(IS_64BIT);
-#endif /* __x86_64__ */
-
if (driverBundlePath)
CFRelease(driverBundlePath);
/*
* 'iterate_printers()' - Iterate over all the printers.
*/
-
static void iterate_printers(iterator_callback_t callBack, void *userdata)
{
- Iterating = 1;
+ Iterating = 1;
- mach_port_t masterPort = 0x0;
- kern_return_t kr = IOMasterPort (bootstrap_port, &masterPort);
+ iterator_reference_t reference = { callBack, userdata, true };
- if (kr == kIOReturnSuccess && masterPort != 0x0)
- {
- iterator_reference_t reference = { callBack, userdata, true };
+ IONotificationPortRef addNotification = IONotificationPortCreate(kIOMasterPortDefault);
- IONotificationPortRef addNotification = IONotificationPortCreate(masterPort);
- io_iterator_t addIterator = IO_OBJECT_NULL;
+ int printingClass = kUSBPrintingClass;
+ int printingSubclass = kUSBPrintingSubclass;
- kr = IOServiceAddMatchingNotification(addNotification, kIOFirstMatchNotification, IOServiceMatching(kIOUSBDeviceClassName),
- &device_added, &reference, &addIterator);
- if (kr == kIOReturnSuccess && addIterator != IO_OBJECT_NULL)
- {
- device_added(&reference, addIterator);
- if (reference.keepRunning)
- {
- CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(addNotification), kCFRunLoopDefaultMode);
- CFRunLoopRun();
- }
- IOObjectRelease(addIterator);
- }
- mach_port_deallocate(mach_task_self(), masterPort);
- }
+ CFNumberRef interfaceClass = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &printingClass);
+ CFNumberRef interfaceSubClass = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &printingSubclass);
- Iterating = 0;
+ CFMutableDictionaryRef usbPrinterMatchDictionary = IOServiceMatching(kIOUSBInterfaceClassName);
+ CFDictionaryAddValue(usbPrinterMatchDictionary, CFSTR("bInterfaceClass"), interfaceClass);
+ CFDictionaryAddValue(usbPrinterMatchDictionary, CFSTR("bInterfaceSubClass"), interfaceSubClass);
+
+ CFRelease(interfaceClass);
+ CFRelease(interfaceSubClass);
+
+ io_iterator_t add_iterator = IO_OBJECT_NULL;
+ IOServiceAddMatchingNotification(addNotification, kIOMatchedNotification,
+ usbPrinterMatchDictionary, &device_added, &reference, &add_iterator);
+ if (add_iterator != IO_OBJECT_NULL)
+ {
+ device_added (&reference, add_iterator);
+ if (reference.keepRunning)
+ {
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(addNotification), kCFRunLoopDefaultMode);
+ CFRunLoopRun();
+ }
+ IOObjectRelease(add_iterator);
+ }
+ Iterating = 0;
}
/*
* 'device_added()' - Device added notifier.
*/
-#define IsPrintingInterface(c,s,p) ((c) == kUSBPrintingInterfaceClass && (s) == kUSBPrintingSubclass && (p) != kUSBPrintingProtocolIPP)
-
static void device_added(void *userdata, io_iterator_t iterator)
{
- iterator_reference_t *reference = userdata;
- io_service_t device;
+ iterator_reference_t *reference = userdata;
+ io_service_t intf;
- while (reference->keepRunning && (device = IOIteratorNext(iterator)) != 0x0)
+ while (reference->keepRunning && (intf = IOIteratorNext(iterator)) != 0x0)
+ {
+ printer_interface_t printerIntf = usb_printer_interface_interface(intf);
+ if (printerIntf != NULL)
{
- UInt32 locationID = 0;
- IOUSBDeviceInterface **devIntf = NULL;
- io_iterator_t intfIterator = IO_OBJECT_NULL;
- io_object_t intf = IO_OBJECT_NULL;
-
- devIntf = usb_device_interface_for_device(device);
- if (devIntf == NULL)
- goto device_added_done;
-
- UInt16 vendorUniqueID;
- if ((*devIntf)->GetDeviceVendor(devIntf, &vendorUniqueID) != kIOReturnSuccess || vendorUniqueID == kAppleVendorID || vendorUniqueID == 0x0A5C)
- goto device_added_done;
-
- if ((*devIntf)->GetLocationID(devIntf, &locationID) != kIOReturnSuccess)
- goto device_added_done;
-
- IOUSBFindInterfaceRequest req = { kIOUSBFindInterfaceDontCare, kIOUSBFindInterfaceDontCare, kIOUSBFindInterfaceDontCare, kIOUSBFindInterfaceDontCare };
- if ((*devIntf)->CreateInterfaceIterator(devIntf, &req, &intfIterator) != kIOReturnSuccess)
- goto device_added_done;
-
- while (reference->keepRunning && (intf = IOIteratorNext(intfIterator)))
- {
- printer_interface_t printerIntf = usb_printer_interface_interface(intf);
- if (printerIntf != NULL)
- {
- UInt8 intfClass = 0, intfSubclass = 0, intfProtocol = 0, intfNumber = 0;
-
- (*printerIntf)->GetInterfaceClass(printerIntf, &intfClass);
- (*printerIntf)->GetInterfaceSubClass(printerIntf, &intfSubclass);
- (*printerIntf)->GetInterfaceProtocol(printerIntf, &intfProtocol);
- (*printerIntf)->GetInterfaceNumber(printerIntf, &intfNumber);
-
- if (IsPrintingInterface(intfClass, intfSubclass, intfProtocol))
- {
- CFStringRef deviceIDString = copy_printer_interface_deviceid(printerIntf, 0);
- if (deviceIDString != NULL)
- {
- reference->keepRunning = reference->callback(userdata, intf, deviceIDString, locationID, intfNumber, 0);
- CFRelease(deviceIDString);
- }
- }
-
- IOUSBInterfaceDescriptor *intfDesc = NULL;
- while (reference->keepRunning && (intfDesc = (IOUSBInterfaceDescriptor *)(*printerIntf)->FindNextAssociatedDescriptor(printerIntf, intfDesc, kUSBInterfaceDesc)))
- {
- intfClass = intfDesc->bInterfaceClass;
- intfSubclass = intfDesc->bInterfaceSubClass;
- intfProtocol = intfDesc->bInterfaceProtocol;
-
- if ((IsPrintingInterface(intfClass, intfSubclass, intfProtocol)))
- {
- CFStringRef deviceIDString = copy_printer_interface_deviceid(printerIntf, intfDesc->bAlternateSetting);
- if (deviceIDString != NULL)
- {
- reference->keepRunning = reference->callback(userdata, intf, deviceIDString, locationID, intfNumber, intfDesc->bAlternateSetting);
- CFRelease(deviceIDString);
- }
- }
- }
- (*printerIntf)->Release(printerIntf);
- }
- IOObjectRelease(intf);
- }
+ UInt8 intfClass = 0, intfSubClass = 0;
- device_added_done:
- if (devIntf != NULL) (*devIntf)->Release(devIntf);
- if (intfIterator != IO_OBJECT_NULL) IOObjectRelease(intfIterator);
-
- IOObjectRelease(device);
+ (*printerIntf)->GetInterfaceClass(printerIntf, &intfClass);
+ (*printerIntf)->GetInterfaceSubClass(printerIntf, &intfSubClass);
+ if (intfClass == kUSBPrintingInterfaceClass && intfSubClass == kUSBPrintingSubclass)
+ reference->keepRunning = reference->callback(intf, printerIntf, userdata);
+ (*printerIntf)->Release(printerIntf);
+ }
+ IOObjectRelease(intf);
}
- /* One last call to the call back now that we are not longer have printers left to iterate...
- */
if (reference->keepRunning && reference->callback)
- reference->keepRunning = reference->callback(reference->userdata, IO_OBJECT_NULL, NULL, 0, 0, 0);
+ reference->keepRunning = reference->callback(IO_OBJECT_NULL, NULL, reference->userdata);
if (!reference->keepRunning)
- CFRunLoopStop(CFRunLoopGetCurrent());
+ CFRunLoopStop(CFRunLoopGetCurrent());
}
/*
* 'list_device_cb()' - list_device iterator callback.
*/
-
-static Boolean list_device_cb(void *refcon, io_service_t obj, CFStringRef deviceIDString, UInt32 deviceLocation, UInt8 interfaceNum, UInt8 alternateSetting)
+static Boolean list_device_cb(io_service_t obj, printer_interface_t printerIntf, void *refcon)
{
- (void)refcon;
- (void)interfaceNum;
- (void)alternateSetting;
+ (void)refcon;
- if (obj != IO_OBJECT_NULL)
- {
- CFStringRef make = deviceIDCopyManufacturer(deviceIDString);
- CFStringRef model = deviceIDCopyModel(deviceIDString);
- CFStringRef serial = deviceIDCopySerialNumber(deviceIDString);
+ if (obj != IO_OBJECT_NULL)
+ {
+ CFStringRef deviceIDString = NULL;
+ CFStringRef make = NULL;
+ CFStringRef model = NULL;
+ CFStringRef serial = NULL;
+ UInt32 intfLocation;
- char uristr[1024], makestr[1024], modelstr[1024], serialstr[1024];
- char optionsstr[1024], idstr[1024], make_modelstr[1024];
+ deviceIDString = copy_printer_interface_deviceid(printerIntf, 0);
+ if (deviceIDString == NULL)
+ goto list_device_done;
- CFStringGetCString(deviceIDString, idstr, sizeof(idstr), kCFStringEncodingUTF8);
- backendGetMakeModel(idstr, make_modelstr, sizeof(make_modelstr));
+ make = deviceIDCopyManufacturer(deviceIDString);
+ model = deviceIDCopyModel(deviceIDString);
+ serial = deviceIDCopySerialNumber(deviceIDString);
- modelstr[0] = '/';
+ char uristr[1024], makestr[1024], modelstr[1024], serialstr[1024];
+ char optionsstr[1024], idstr[1024], make_modelstr[1024];
- if (make == NULL || !CFStringGetCString(make, makestr, sizeof(makestr), kCFStringEncodingUTF8))
- strlcpy(makestr, "Unknown", sizeof(makestr));
+ CFStringGetCString(deviceIDString, idstr, sizeof(idstr), kCFStringEncodingUTF8);
+ backendGetMakeModel(idstr, make_modelstr, sizeof(make_modelstr));
- if (model == NULL || !CFStringGetCString(model, &modelstr[1], sizeof(modelstr)-1, kCFStringEncodingUTF8))
- strlcpy(modelstr + 1, "Printer", sizeof(modelstr) - 1);
+ modelstr[0] = '/';
- optionsstr[0] = '\0';
- if (serial != NULL && CFStringGetCString(serial, serialstr, sizeof(serialstr), kCFStringEncodingUTF8))
- snprintf(optionsstr, sizeof(optionsstr), "?serial=%s", serialstr);
- else if (deviceLocation != 0)
- snprintf(optionsstr, sizeof(optionsstr), "?location=%x", (unsigned)deviceLocation);
+ if (make == NULL || !CFStringGetCString(make, makestr, sizeof(makestr), kCFStringEncodingUTF8))
+ strlcpy(makestr, "Unknown", sizeof(makestr));
- httpAssembleURI(HTTP_URI_CODING_ALL, uristr, sizeof(uristr), "usb", NULL, makestr, 0, modelstr);
- strlcat(uristr, optionsstr, sizeof(uristr));
+ if (model == NULL || !CFStringGetCString(model, &modelstr[1], sizeof(modelstr)-1, kCFStringEncodingUTF8))
+ strlcpy(modelstr + 1, "Printer", sizeof(modelstr) - 1);
- cupsBackendReport("direct", uristr, make_modelstr, make_modelstr, idstr,
- NULL);
+ optionsstr[0] = '\0';
+ if (serial != NULL && CFStringGetCString(serial, serialstr, sizeof(serialstr), kCFStringEncodingUTF8))
+ snprintf(optionsstr, sizeof(optionsstr), "?serial=%s", serialstr);
+ else if ((*printerIntf)->GetLocationID(printerIntf, &intfLocation) == kIOReturnSuccess)
+ snprintf(optionsstr, sizeof(optionsstr), "?location=%x", (unsigned)intfLocation);
- if (make != NULL) CFRelease(make);
- if (model != NULL) CFRelease(model);
- if (serial != NULL) CFRelease(serial);
- }
+ httpAssembleURI(HTTP_URI_CODING_ALL, uristr, sizeof(uristr), "usb", NULL, makestr, 0, modelstr);
+ strlcat(uristr, optionsstr, sizeof(uristr));
+
+ cupsBackendReport("direct", uristr, make_modelstr, make_modelstr, idstr,
+ NULL);
+ list_device_done:
- return obj != IO_OBJECT_NULL;
+ if (make != NULL) CFRelease(make);
+ if (model != NULL) CFRelease(model);
+ if (serial != NULL) CFRelease(serial);
+ }
+ return obj != IO_OBJECT_NULL;
}
/*
* 'find_device_cb()' - print_device iterator callback.
*/
-static Boolean find_device_cb(void *refcon, io_service_t obj, CFStringRef deviceIDString, UInt32 deviceLocation, UInt8 interfaceNum, UInt8 alternateSetting)
+static Boolean find_device_cb(io_service_t obj, printer_interface_t printerIntf, void *refcon)
{
- Boolean keepLooking = true;
+ (void)refcon;
+
+ Boolean keepLooking = true;
- if (obj != IO_OBJECT_NULL)
+ if (obj != IO_OBJECT_NULL)
+ {
+ CFStringRef deviceIDString = NULL;
+ CFStringRef make = NULL;
+ CFStringRef model = NULL;
+ CFStringRef serial = NULL;
+
+ deviceIDString = copy_printer_interface_deviceid(printerIntf, 0);
+ if (deviceIDString == NULL)
+ goto find_device_done;
+
+ make = deviceIDCopyManufacturer(deviceIDString);
+ model = deviceIDCopyModel(deviceIDString);
+ serial = deviceIDCopySerialNumber(deviceIDString);
+
+ if (make && CFStringCompare(make, g.make, kCFCompareCaseInsensitive) == kCFCompareEqualTo)
{
- CFStringRef make = deviceIDCopyManufacturer(deviceIDString);
- CFStringRef model = deviceIDCopyModel(deviceIDString);
- CFStringRef serial = deviceIDCopySerialNumber(deviceIDString);
+ if (model && CFStringCompare(model, g.model, kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+ {
+ UInt8 intfAltSetting = 0, intfNumber = 0, intfProtocol = 0;
+ UInt32 intfLocation = 0;
+
+ (*printerIntf)->GetInterfaceProtocol(printerIntf, &intfProtocol);
+ (*printerIntf)->GetAlternateSetting(printerIntf, &intfAltSetting);
+ (*printerIntf)->GetInterfaceNumber(printerIntf, &intfNumber);
+ (*printerIntf)->GetLocationID(printerIntf, &intfLocation);
- if (make && CFStringCompare(make, g.make, kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+ if (intfProtocol == kUSBPrintingProtocolIPP)
+ return keepLooking;
+
+ if (g.serial != NULL && CFStringGetLength(g.serial) > 0)
{
- if (model && CFStringCompare(model, g.model, kCFCompareCaseInsensitive) == kCFCompareEqualTo)
- {
- if (g.serial != NULL && CFStringGetLength(g.serial) > 0)
- {
- if (serial != NULL && CFStringCompare(serial, g.serial, kCFCompareCaseInsensitive) == kCFCompareEqualTo)
- {
- IOObjectRetain(obj);
- g.printer_obj = obj;
- g.location = deviceLocation;
- g.alternateSetting = alternateSetting;
- keepLooking = false;
- }
- }
- else
- {
- if (g.printer_obj != 0)
- IOObjectRelease(g.printer_obj);
-
- g.alternateSetting = alternateSetting;
- g.printer_obj = obj;
- IOObjectRetain(obj);
-
- if (g.location == 0 || g.location == deviceLocation)
- keepLooking = false;
- }
-
- if ( !keepLooking )
- g.interfaceNum = interfaceNum;
- }
+ if (serial != NULL && CFStringCompare(serial, g.serial, kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+ {
+ g.interfaceProtocol = intfProtocol;
+ g.location = intfLocation;
+ g.alternateSetting = intfAltSetting;
+ g.printer_obj = obj;
+ IOObjectRetain(obj);
+ keepLooking = false;
+ }
}
-
- if (make) CFRelease(make);
- if (model) CFRelease(model);
- if (serial) CFRelease(serial);
- }
- else
- {
- keepLooking = (g.printer_obj == 0);
- if (obj == IO_OBJECT_NULL && keepLooking)
+ else
{
- CFRunLoopTimerContext context = { 0, refcon, NULL, NULL, NULL };
- CFRunLoopTimerRef timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() + 1.0, 10, 0x0, 0x0, status_timer_cb, &context);
- if (timer != NULL)
- {
- CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
- g.status_timer = timer;
- }
+ if (g.printer_obj != 0)
+ IOObjectRelease(g.printer_obj);
+
+ if (g.location == 0 || g.location == intfLocation)
+ keepLooking = false;
+
+ g.location = intfLocation;
+ g.alternateSetting = intfAltSetting;
+ g.interfaceProtocol = intfProtocol;
+ g.printer_obj = obj;
+ IOObjectRetain(obj);
}
+
+ if (!keepLooking)
+ g.interfaceNum = intfNumber;
+ }
}
- if (!keepLooking && g.status_timer != NULL)
+ find_device_done:
+ if (deviceIDString != NULL) CFRelease(deviceIDString);
+ if (make != NULL) CFRelease(make);
+ if (model != NULL) CFRelease(model);
+ if (serial != NULL) CFRelease(serial);
+ }
+ else
+ {
+ keepLooking = (g.printer_obj == 0 && g.interfaceProtocol != kUSBPrintingProtocolIPP);
+ if (obj == IO_OBJECT_NULL && keepLooking)
{
- fputs("STATE: -offline-report\n", stderr);
- _cupsLangPrintFilter(stderr, "INFO", _("The printer is now online."));
- CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), g.status_timer, kCFRunLoopDefaultMode);
- CFRelease(g.status_timer);
- g.status_timer = NULL;
+ CFRunLoopTimerContext context = { 0, refcon, NULL, NULL, NULL };
+ CFRunLoopTimerRef timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() + 1.0, 10, 0x0, 0x0, status_timer_cb, &context);
+ if (timer != NULL)
+ {
+ CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
+ g.status_timer = timer;
+ }
}
+ }
+
+ if (!keepLooking && g.status_timer != NULL)
+ {
+ fputs("STATE: -offline-report\n", stderr);
+ _cupsLangPrintFilter(stderr, "INFO", _("The printer is now online."));
+ CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), g.status_timer, kCFRunLoopDefaultMode);
+ CFRelease(g.status_timer);
+ g.status_timer = NULL;
+ }
- return keepLooking;
+ return keepLooking;
}
static CFStringRef deviceIDCopySerialNumber(CFStringRef deviceID)
return intf;
}
-static IOUSBDeviceInterface **usb_device_interface_for_device(io_service_t usbDevice)
-{
- IOUSBDeviceInterface ** intf = NULL;
- IOCFPlugInInterface **plugin = NULL;
- SInt32 score;
-
- int kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score);
- if (kr == kIOReturnSuccess)
- {
- (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID *)&intf);
- IODestroyPlugInInterface(plugin);
- }
-
- return intf;
-}
-
-
static CFStringRef copy_printer_interface_deviceid(printer_interface_t printer, UInt8 alternateSetting)
{
// I have tried to make this function as neat as I can, but the possibility of needing to resend
/* This request takes the 0 based configuration index. IOKit returns a 1 based configuration index */
configurationIndex -= 1;
- bzero(&request, sizeof(request));
+ memset(&request, 0, sizeof(request));
request.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBClass, kUSBInterface);
request.bRequest = kUSBPrintClassGetDeviceID;
IOUSBDevRequestTO request;
IOUSBDeviceDescriptor desc;
- bzero(&request, sizeof(request));
+ memset(&request, 0, sizeof(request));
request.bmRequestType = USBmakebmRequestType( kUSBIn, kUSBStandard, kUSBDevice );
request.bRequest = kUSBRqGetDescriptor;
CFStringAppendFormat(extras, NULL, CFSTR("MDL:%@;"), model);
}
- if (serial == NULL && desc.iSerialNumber != 0)
+ if (desc.iSerialNumber != 0)
{
- serial = copy_printer_interface_indexed_description(printer, desc.iSerialNumber, kUSBLanguageEnglish);
- if (serial && CFStringGetLength(serial) > 0)
- CFStringAppendFormat(extras, NULL, CFSTR("SERN:%@;"), serial);
+ // Always look at the USB serial number since some printers
+ // incorrectly include a bogus static serial number in their
+ // IEEE-1284 device ID string...
+ CFStringRef userial = copy_printer_interface_indexed_description(printer, desc.iSerialNumber, kUSBLanguageEnglish);
+ if (userial && CFStringGetLength(userial) > 0 && (serial == NULL || CFStringCompare(serial, userial, kCFCompareCaseInsensitive) != kCFCompareEqualTo))
+ {
+ if (serial != NULL)
+ {
+ // 1284 serial number doesn't match USB serial number, so replace the existing SERN: in device ID
+ CFRange range = CFStringFind(ret, serial, 0);
+ CFMutableStringRef deviceIDString = CFStringCreateMutableCopy(NULL, 0, ret);
+ CFStringReplace(deviceIDString, range, userial);
+ CFRelease(ret);
+ ret = deviceIDString;
+
+ CFRelease(serial);
+ }
+ else
+ {
+ // No 1284 serial number so add SERN: with USB serial number to device ID
+ CFStringAppendFormat(extras, NULL, CFSTR("SERN:%@;"), userial);
+ }
+ serial = userial;
+ }
+ else if (userial != NULL)
+ CFRelease(userial);
}
if (ret != NULL)
if (ret != NULL)
{
- /* Remove special characters from the serial number */
- CFRange range = (serial != NULL ? CFStringFind(serial, CFSTR("+"), 0) : CFRangeMake(0, 0));
- if (range.length == 1)
- {
- range = CFStringFind(ret, serial, 0);
+ /* Remove special characters from the serial number */
+ CFRange range = (serial != NULL ? CFStringFind(serial, CFSTR("+"), 0) : CFRangeMake(0, 0));
+ if (range.length == 1)
+ {
+ range = CFStringFind(ret, serial, 0);
- CFMutableStringRef deviceIDString = CFStringCreateMutableCopy(NULL, 0, ret);
- CFRelease(ret);
+ CFMutableStringRef deviceIDString = CFStringCreateMutableCopy(NULL, 0, ret);
+ CFRelease(ret);
- ret = deviceIDString;
- CFStringFindAndReplace(deviceIDString, CFSTR("+"), CFSTR(""), range, 0);
- }
+ ret = deviceIDString;
+ CFStringFindAndReplace(deviceIDString, CFSTR("+"), CFSTR(""), range, 0);
+ }
}
if (manufacturer != NULL)
UInt8 description[256]; // Max possible descriptor length
IOUSBDevRequestTO request;
- bzero(description, 2);
+ memset(description, 0, 2);
request.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
request.bRequest = kUSBRqGetDescriptor;
err = (*printer)->ControlRequestTO(printer, 0, &request);
if (err != kIOReturnSuccess && err != kIOReturnOverrun)
{
- bzero(description, request.wLength);
+ memset(description, 0, request.wLength);
// Let's try again full length. Here's why:
// On USB 2.0 controllers, we will not get an overrun error. We just get a "babble" error
request.wValue = (kUSBStringDesc << 8) | index;
request.wIndex = language;
- bzero(description, length);
+ memset(description, 0, length);
request.wLength = (UInt16)length;
request.pData = &description;
request.completionTimeout = 0;
value);
}
else if (!_cups_strcasecmp(name, "serial"))
- strlcpy(serial, value, serial_size);
+ strlcpy(serial, value, (size_t)serial_size);
else if (!_cups_strcasecmp(name, "location") && location)
*location = (UInt32)strtoul(value, NULL, 16);
}
}
#pragma mark -
-#if defined(__i386__) || defined(__x86_64__)
+#if defined(__arm64e__)
/*!
* @function run_legacy_backend
*
- * @abstract Starts child backend process running as a ppc or i386 executable.
+ * @abstract Starts child backend process running as a x86_64 executable.
*
* @result Never returns; always calls exit().
*
/*
- * If we're running as x86_64 or i386 and couldn't load the class driver
- * (because it's ppc or i386), then try to re-exec ourselves in ppc or i386
- * mode to try again. If we don't have a ppc or i386 architecture we may be
+ * If we're running as ARM and couldn't load the class driver
+ * (because it's x86_64, i386 or ppc), then try to re-exec ourselves in x86_64
+ * mode to try again. If we don't have that architecture we may be
* running with the same architecture again so guard against this by setting
* and testing an environment variable...
*/
-# ifdef __x86_64__
- usb_legacy_status = getenv("USB_I386_STATUS");
-# else
- usb_legacy_status = getenv("USB_PPC_STATUS");
-# endif /* __x86_64__ */
+ usb_legacy_status = getenv("USB_LEGACY_STATUS");
if (!usb_legacy_status)
{
- log_usb_class_driver(IS_NOT_64BIT);
-
/*
* Setup a SIGTERM handler then block it before forking...
*/
* Set the environment variable...
*/
-# ifdef __x86_64__
- setenv("USB_I386_STATUS", "1", false);
-# else
- setenv("USB_PPC_STATUS", "1", false);
-# endif /* __x86_64__ */
+ setenv("USB_LEGACY_STATUS", "1", false);
/*
* Tell the kernel to use the specified CPU architecture...
*/
-# ifdef __x86_64__
- cpu_type_t cpu = CPU_TYPE_I386;
-# else
- cpu_type_t cpu = CPU_TYPE_POWERPC;
-# endif /* __x86_64__ */
+ cpu_type_t cpu = CPU_TYPE_X86_64;
size_t ocount = 1;
posix_spawnattr_t attrs;
posix_spawnattr_setsigdefault(&attrs, &oldmask);
if (posix_spawnattr_setbinpref_np(&attrs, 1, &cpu, &ocount) || ocount != 1)
{
-# ifdef __x86_64__
- perror("DEBUG: Unable to set binary preference to i386");
-# else
- perror("DEBUG: Unable to set binary preference to ppc");
-# endif /* __x86_64__ */
+ perror("DEBUG: Unable to set binary preference to X86_64");
_cupsLangPrintFilter(stderr, "ERROR",
_("Unable to use legacy USB class driver."));
exit(CUPS_BACKEND_STOP);
exit(exitstatus);
}
-#endif /* __i386__ || __x86_64__ */
-
/*
* 'sigterm_handler()' - SIGTERM handler.
static void
sigterm_handler(int sig) /* I - Signal */
{
-#if defined(__i386__) || defined(__x86_64__)
/*
* If we started a child process pass the signal on to it...
*/
_exit(0);
else
{
- write(2, "DEBUG: Child crashed.\n", 22);
+ backendMessage("DEBUG: Child crashed.\n");
_exit(CUPS_BACKEND_STOP);
}
}
-#endif /* __i386__ || __x86_64__ */
}
+#endif /* __arm64e__ */
/*
*status = CUPS_SC_STATUS_OK;
}
-
-
-static void
-log_usb_class_driver(int is_64bit) /* I - Is the USB class driver 64-bit? */
-{
- /*
- * Report the usage of legacy USB class drivers to Apple if the user opts into providing
- * feedback to Apple...
- */
-
- aslmsg aslm = asl_new(ASL_TYPE_MSG);
- if (aslm)
- {
- ppd_file_t *ppd = ppdOpenFile(getenv("PPD"));
- const char *make_model = ppd ? ppd->nickname : NULL;
- ppd_attr_t *version = ppdFindAttr(ppd, "FileVersion", "");
-
- asl_set(aslm, "com.apple.message.domain", "com.apple.printing.usb.64bit");
- asl_set(aslm, "com.apple.message.result", is_64bit ? "yes" : "no");
- asl_set(aslm, "com.apple.message.signature", make_model ? make_model : "Unknown");
- asl_set(aslm, "com.apple.message.signature2", version ? version->value : "?.?");
- asl_set(aslm, "com.apple.message.summarize", "YES");
- asl_log(NULL, aslm, ASL_LEVEL_NOTICE, "");
- asl_free(aslm);
- }
-}
-
-
-/*
- * End of "$Id$".
- */