static IOUSBInterfaceInterface220 **usb_interface220_for_service(io_service_t usbClass);
static IOUSBDeviceInterface **usb_device_interface_for_device(io_service_t usbDevice);
static CFStringRef copy_printer_interface_deviceid(IOUSBInterfaceInterface220 **printer, UInt8 alternateSetting);
-static CFStringRef printer_interface_indexed_description(IOUSBInterfaceInterface220 ** printer, UInt8 index, UInt16 language);
+static CFStringRef copy_printer_interface_indexed_description(IOUSBInterfaceInterface220 ** printer, UInt8 index, UInt16 language);
static CFStringRef deviceIDCopyManufacturer(CFStringRef deviceID);
static CFStringRef deviceIDCopyModel(CFStringRef deviceID);
static CFStringRef deviceIDCopySerialNumber(CFStringRef deviceID);
static void iterate_printers(iterator_callback_t callBack, void *userdata)
{
Iterating = 1;
-
+
mach_port_t masterPort = 0x0;
kern_return_t kr = IOMasterPort (bootstrap_port, &masterPort);
-
+
if (kr == kIOReturnSuccess && masterPort != 0x0)
{
iterator_reference_t reference = { callBack, userdata, true };
-
+
IONotificationPortRef addNotification = IONotificationPortCreate(masterPort);
io_iterator_t addIterator = IO_OBJECT_NULL;
-
+
kr = IOServiceAddMatchingNotification(addNotification, kIOFirstMatchNotification, IOServiceMatching(kIOUSBDeviceClassName),
&device_added, &reference, &addIterator);
if (kr == kIOReturnSuccess && addIterator != IO_OBJECT_NULL)
}
mach_port_deallocate(mach_task_self(), masterPort);
}
-
+
Iterating = 0;
}
{
iterator_reference_t *reference = userdata;
io_service_t device;
-
+
while (reference->keepRunning && (device = IOIteratorNext(iterator)) != 0x0)
{
UInt32 locationID = 0;
}
}
- IOUSBInterfaceDescriptor *intfDesc = nil;
+ IOUSBInterfaceDescriptor *intfDesc = NULL;
while (reference->keepRunning && (intfDesc = (IOUSBInterfaceDescriptor *)(*intf220)->FindNextAssociatedDescriptor(intf220, intfDesc, kUSBInterfaceDesc)))
{
intfClass = intfDesc->bInterfaceClass;
}
(*intf220)->Release(intf220);
}
+ IOObjectRelease(intf);
}
device_added_done:
IOObjectRelease(device);
}
-
+
/* 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);
-
+
if (!reference->keepRunning)
CFRunLoopStop(CFRunLoopGetCurrent());
}
if (obj != IO_OBJECT_NULL)
{
- CFStringRef make = NULL;
- CFStringRef model = NULL;
- CFStringRef serial = NULL;
-
+ CFStringRef make = deviceIDCopyManufacturer(deviceIDString);
+ CFStringRef model = deviceIDCopyModel(deviceIDString);
+ CFStringRef serial = deviceIDCopySerialNumber(deviceIDString);
+
char uristr[1024], makestr[1024], modelstr[1024], serialstr[1024];
char optionsstr[1024], idstr[1024], make_modelstr[1024];
-
+
CFStringGetCString(deviceIDString, idstr, sizeof(idstr), kCFStringEncodingUTF8);
backendGetMakeModel(idstr, make_modelstr, sizeof(make_modelstr));
-
+
modelstr[0] = '/';
-
+
if (make == NULL || !CFStringGetCString(make, makestr, sizeof(makestr), kCFStringEncodingUTF8))
strlcpy(makestr, "Unknown", sizeof(makestr));
-
+
if (model == NULL || !CFStringGetCString(model, &modelstr[1], sizeof(modelstr)-1, kCFStringEncodingUTF8))
strlcpy(modelstr + 1, "Printer", sizeof(modelstr) - 1);
-
+
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);
-
+
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);
- }
+ if (make != NULL) CFRelease(make);
+ if (model != NULL) CFRelease(model);
+ if (serial != NULL) CFRelease(serial);
+ }
+
return obj != IO_OBJECT_NULL;
}
static Boolean find_device_cb(void *refcon, io_service_t obj, CFStringRef deviceIDString, UInt32 deviceLocation, UInt8 interfaceNum, UInt8 alternateSetting)
{
Boolean keepLooking = true;
-
+
if (obj != IO_OBJECT_NULL)
{
CFStringRef make = deviceIDCopyManufacturer(deviceIDString);
CFStringRef model = deviceIDCopyModel(deviceIDString);
CFStringRef serial = deviceIDCopySerialNumber(deviceIDString);
-
+
if (make && CFStringCompare(make, g.make, kCFCompareCaseInsensitive) == kCFCompareEqualTo)
{
if (model && CFStringCompare(model, g.model, kCFCompareCaseInsensitive) == kCFCompareEqualTo)
{
IOObjectRetain(obj);
g.printer_obj = obj;
+ g.location = deviceLocation;
g.alternateSetting = alternateSetting;
keepLooking = false;
}
{
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 (make) CFRelease(make);
if (model) CFRelease(model);
if (serial) CFRelease(serial);
}
}
}
-
+
if (!keepLooking && g.status_timer != NULL)
{
fputs("STATE: -offline-report\n", stderr);
CFRelease(g.status_timer);
g.status_timer = NULL;
}
-
+
return keepLooking;
}
static CFStringRef deviceIDCopySerialNumber(CFStringRef deviceID)
{
CFStringRef serialKeys[] = { CFSTR("SN:"), CFSTR("SERN:"), NULL };
-
+
return copy_value_for_key(deviceID, serialKeys);
}
#define kDefaultNoDataTimeout 5000L
#define pack_device_id_wIndex(intf, alt) ((UInt16)((((UInt16)(intf)) << 8) | ((UInt8)(alt))))
- if (printer == nil)
- return nil;
+ if (printer == NULL)
+ return NULL;
IOReturn err = kIOReturnError;
}
CFStringRef manufacturer = deviceIDCopyManufacturer(ret);
- CFStringRef model = deviceIDCopyManufacturer(ret);
+ CFStringRef model = deviceIDCopyModel(ret);
CFStringRef serial = deviceIDCopySerialNumber(ret);
if (manufacturer == NULL || serial == NULL || model == NULL)
CFMutableStringRef extras = CFStringCreateMutable(NULL, 0);
if (manufacturer == NULL)
{
- manufacturer = printer_interface_indexed_description(printer, desc.iManufacturer, kUSBLanguageEnglish);
- if (CFStringGetLength(manufacturer) > 0)
+ manufacturer = copy_printer_interface_indexed_description(printer, desc.iManufacturer, kUSBLanguageEnglish);
+ if (manufacturer && CFStringGetLength(manufacturer) > 0)
CFStringAppendFormat(extras, NULL, CFSTR("MFG:%@;"), manufacturer);
}
if (model == NULL)
{
- model = printer_interface_indexed_description(printer, desc.iProduct, kUSBLanguageEnglish);
- if (CFStringGetLength(model) > 0)
- CFStringAppendFormat(extras, NULL, CFSTR("MDL:%@;"), manufacturer);
+ model = copy_printer_interface_indexed_description(printer, desc.iProduct, kUSBLanguageEnglish);
+ if (model && CFStringGetLength(model) > 0)
+ CFStringAppendFormat(extras, NULL, CFSTR("MDL:%@;"), model);
}
if (serial == NULL && desc.iSerialNumber != 0)
{
- serial = printer_interface_indexed_description(printer, desc.iSerialNumber, kUSBLanguageEnglish);
- if (CFStringGetLength(serial) > 0)
+ serial = copy_printer_interface_indexed_description(printer, desc.iSerialNumber, kUSBLanguageEnglish);
+ if (serial && CFStringGetLength(serial) > 0)
CFStringAppendFormat(extras, NULL, CFSTR("SERN:%@;"), serial);
}
}
}
- if (manufacturer != NULL)
- CFRelease(manufacturer);
- if (model != NULL)
- CFRelease(model);
- if (serial != NULL)
- CFRelease(serial);
-
-
+ 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)
ret = deviceIDString;
CFStringFindAndReplace(deviceIDString, CFSTR("+"), CFSTR(""), range, 0);
}
+ }
+
+ if (manufacturer != NULL)
+ CFRelease(manufacturer);
+
+ if (model != NULL)
+ CFRelease(model);
+
+ if (serial != NULL)
+ CFRelease(serial);
- return (CFStringGetLength(ret) > 0 ? ret : nil);
+ if (ret != NULL && CFStringGetLength(ret) == 0)
+ {
+ CFRelease(ret);
+ return NULL;
+ }
+
+ return ret;
}
-static CFStringRef printer_interface_indexed_description(IOUSBInterfaceInterface220 ** printer, UInt8 index, UInt16 language)
+static CFStringRef copy_printer_interface_indexed_description(IOUSBInterfaceInterface220 ** printer, UInt8 index, UInt16 language)
{
IOReturn err;
UInt8 description[256]; // Max possible descriptor length
err = (*printer)->ControlRequestTO(printer, 0, &request);
if (err != kIOReturnSuccess && err != kIOReturnUnderrun)
- return nil;
+ return NULL;
}
unsigned int length = description[0];
err = (*printer)->ControlRequestTO(printer, 0, &request);
if (err != kIOReturnSuccess)
- return nil;
+ return NULL;
if (description[1] != kUSBStringDesc)
- return nil;
+ return NULL;
if ((description[0] & 1) != 0)
description[0] &= 0xfe;
*datalen = (int)strlen(data);
else
*datalen = 0;
-
+
CFRelease(deviceIDString);
}
else