static OSStatus WorkaroundNetworkPrefsBug(CFDictionaryRef *entitiesDictPtr) // If this is an Ethernet interface and LCPEchoEnabled is false, // set it to true. This works around what I think is a bug in // the Network preferences panel <rdar://problem/3182846> where the // LCPEchoEnabled flag is mysteriously set to false for PCI Ethernet // interfaces. { OSStatus err; CFStringRef hardwarePath[2]; CFStringRef lcpPath[2]; CFStringRef hardwareStr; CFNumberRef lcpValue; long enabled; hardwarePath[0] = kSCEntNetInterface; hardwarePath[1] = kSCPropNetInterfaceHardware; lcpPath[0] = kSCEntNetPPP; lcpPath[1] = kSCPropNetPPPLCPEchoEnabled; hardwareStr = NULL; // just to make debugging easier lcpValue = NULL; err = noErr; if ( CFQDictionaryGetValueAtPath(*entitiesDictPtr, (const void **) hardwarePath, 2, (const void **) &hardwareStr) == noErr && CFEqual(hardwareStr, kSCEntNetEthernet) && CFQDictionaryGetValueAtPath(*entitiesDictPtr, (const void **) lcpPath, 2, (const void **) &lcpValue) == noErr && CFNumberGetValue(lcpValue, kCFNumberLongType, &enabled) && (enabled == 0) ) { CFMutableDictionaryRef newDict; CFNumberRef numRef; if ( ! gRunQuiet ) { fprintf(stderr, "Applied workaround\n"); } numRef = NULL; newDict = CFDictionaryCreateMutableCopy(NULL, 0, *entitiesDictPtr); err = CFQError(newDict); if (err == noErr) { enabled = true; numRef = CFNumberCreate(NULL, kCFNumberLongType, &enabled); err = CFQError(numRef); } if (err == noErr) { err = CFQDictionarySetValueAtPath(newDict, (const void **) lcpPath, 2, numRef); } if (err == noErr) { CFQRelease(*entitiesDictPtr); *entitiesDictPtr = newDict; newDict = NULL; } CFQRelease(newDict); CFQRelease(numRef); } return err; }
extern pascal OSStatus CFQDictionarySetValueAtPathArray(CFMutableDictionaryRef dict, CFArrayRef path, const void *value) // See comment in header. { OSStatus err; CFTypeRef * pathElements; assert( dict != NULL); assert( path != NULL); err = PathArrayHelper(path, &pathElements); if (err == noErr) { err = CFQDictionarySetValueAtPath(dict, pathElements, CFArrayGetCount(path), value); } if (pathElements != NULL) { free(pathElements); } return err; }