static kern_return_t register_bootstrap_service(void) { kern_return_t kr; mach_port_t service_send_port, service_rcv_port; // Let us attempt to check in.... This routine will look up the service // by name and attempt to return receive rights to the service port. kr = bootstrap_check_in(bootstrap_port, (char *)SERVICE_NAME, &service_rcv_port); if (kr == KERN_SUCCESS) server_priv_port = bootstrap_port; else if (kr == BOOTSTRAP_UNKNOWN_SERVICE) { // The service does not exist, so let us create it.... kr = bootstrap_create_server(bootstrap_port, SERVICE_CMD, getuid(), // server uid FALSE, // not on-demand &server_priv_port); if (kr != KERN_SUCCESS) return kr; // We can now use server_priv_port to declare services associated // with this server by calling bootstrap_create_service() and passing // server_priv_port as the bootstrap port. // Create a service called SERVICE_NAME, and return send rights to // that port in service_send_port. kr = bootstrap_create_service(server_priv_port, (char *)SERVICE_NAME, &service_send_port); if (kr != KERN_SUCCESS) { mach_port_deallocate(mach_task_self(), server_priv_port); return kr; } // Check in and get receive rights to the service port of the service. kr = bootstrap_check_in(server_priv_port, (char *)SERVICE_NAME, &service_rcv_port); if (kr != KERN_SUCCESS) { mach_port_deallocate(mach_task_self(), server_priv_port); mach_port_deallocate(mach_task_self(), service_send_port); return kr; } } // We are not a Mach port server, so we do not need this port. However, // we still will have a service with the Bootstrap Server, and so we // will be relaunched if we exit. mach_port_destroy(mach_task_self(), service_rcv_port); return kr; }
void* AppleCMIODPSampleNewPlugIn(CFAllocatorRef allocator, CFUUIDRef requestedTypeUUID) { if (not CFEqual(requestedTypeUUID, kCMIOHardwarePlugInTypeID)) return 0; try { // Before going any further, make sure the SampleAssistant process is registerred with Mach's bootstrap service. Normally, this would be done by having an appropriately // configured plist in /Library/LaunchDaemons, but if that is done then the process will be owned by root, thus complicating the debugging process. Therefore, in the event that the // plist is missing (as would be the case for most debugging efforts) attempt to register the SampleAssistant now. It will fail gracefully if allready registered. mach_port_t assistantServicePort; name_t assistantServiceName = "com.apple.cmio.DPA.Sample"; kern_return_t err = bootstrap_look_up(bootstrap_port, assistantServiceName, &assistantServicePort); if (BOOTSTRAP_SUCCESS != err) { // Create an URL to SampleAssistant that resides at "/Library/CoreMediaIO/Plug-Ins/DAL/Sample.plugin/Contents/Resources/SampleAssistant" CACFURL assistantURL(CFURLCreateWithFileSystemPath(NULL, CFSTR("/Library/CoreMediaIO/Plug-Ins/DAL/Sample.plugin/Contents/Resources/SampleAssistant"), kCFURLPOSIXPathStyle, false)); ThrowIf(not assistantURL.IsValid(), CAException(-1), "AppleCMIODPSampleNewPlugIn: unable to create URL for the SampleAssistant"); // Get the maximum size of the of the file system representation of the SampleAssistant's absolute path CFIndex length = CFStringGetMaximumSizeOfFileSystemRepresentation(CACFString(CFURLCopyFileSystemPath(CACFURL(CFURLCopyAbsoluteURL(assistantURL.GetCFObject())).GetCFObject(), kCFURLPOSIXPathStyle)).GetCFString()); // Get the file system representation CAAutoFree<char> path(length); (void) CFURLGetFileSystemRepresentation(assistantURL.GetCFObject(), true, reinterpret_cast<UInt8*>(path.get()), length); mach_port_t assistantServerPort; err = bootstrap_create_server(bootstrap_port, path, getuid(), true, &assistantServerPort); ThrowIf(BOOTSTRAP_SUCCESS != err, CAException(err), "AppleCMIODPSampleNewPlugIn: couldn't create server"); err = bootstrap_check_in(assistantServerPort, assistantServiceName, &assistantServicePort); // The server port is no longer needed so get rid of it (void) mach_port_deallocate(mach_task_self(), assistantServerPort); // Make sure the call to bootstrap_create_service() succeeded ThrowIf(BOOTSTRAP_SUCCESS != err, CAException(err), "AppleCMIODPSampleNewPlugIn: couldn't create SampleAssistant service port"); } // The service port is not longer needed so get rid of it (void) mach_port_deallocate(mach_task_self(), assistantServicePort); CMIO::DP::Sample::PlugIn* plugIn = new CMIO::DP::Sample::PlugIn(requestedTypeUUID); plugIn->Retain(); return plugIn->GetInterface(); } catch (...) { return NULL; } }
static void regServ(uid_t u, bool on_demand, bool is_kunc, const char *serv_name, const char *serv_cmd) { kern_return_t kr; mach_port_t msr, msv, mhp; if ((kr = bootstrap_create_server(bootstrap_port, (char*)serv_cmd, u, on_demand, &msr)) != KERN_SUCCESS) { fprintf(stderr, "%s: bootstrap_create_server(): %d\n", argv0, kr); return; } if ((kr = bootstrap_create_service(msr, (char*)serv_name, &msv)) != KERN_SUCCESS) { fprintf(stderr, "%s: bootstrap_register(): %d\n", argv0, kr); return; } if (is_kunc) { mhp = mach_host_self(); if ((kr = host_set_UNDServer(mhp, msv)) != KERN_SUCCESS) { fprintf(stderr, "%s: host_set_UNDServer(): %s\n", argv0, mach_error_string(kr)); return; } mach_port_deallocate(mach_task_self(), mhp); } }