SDP_PlugIn::SDP_PlugIn(const AudioDriverPlugInHostInfo& inHostInfo) : HP_DriverPlugIn(inHostInfo), mEngineConnection(IO_OBJECT_NULL), mConnectionNotificationPort(NULL) { // create the Mach port for connection notifications mConnectionNotificationPort = new CACFMachPort((CFMachPortCallBack)MachPortCallBack, this); // add the run loop source for the connection notifications AudioHardwareAddRunLoopSource(mConnectionNotificationPort->GetRunLoopSource()); // open a connection to the engine kern_return_t theKernelError = IOServiceOpen(mHostInfo.mIOAudioEngine, mach_task_self(), 0, &mEngineConnection); ThrowIfKernelError(theKernelError, CAException(theKernelError), "SDP_PlugIn::SDP_PlugIn: Cannot connect to the IOAudioEngine."); // tell the connection about our notification mach_port_t theKernelError = IOConnectSetNotificationPort(mEngineConnection, 0, mConnectionNotificationPort->GetMachPort(), 0); ThrowIfKernelError(theKernelError, CAException(theKernelError), "SDP_PlugIn::SDP_PlugIn: Cannot set the device's notification port."); }
/*! Opens a connection to the iSCSI initiator. A connection must be * successfully opened before any of the supporting functions below can be * called. */ errno_t iSCSIKernelInitialize(iSCSIKernelNotificationCallback callback) { kern_return_t result; // Create a dictionary to match iSCSIkext CFMutableDictionaryRef matchingDict = NULL; matchingDict = IOServiceMatching(kiSCSIVirtualHBA_IOClassName); service = IOServiceGetMatchingService(kIOMasterPortDefault,matchingDict); // Check to see if the driver was found in the I/O registry if(service == IO_OBJECT_NULL) return kIOReturnNotFound; // Using the service handle, open a connection result = IOServiceOpen(service,mach_task_self(),0,&connection); if(result != kIOReturnSuccess) { IOObjectRelease(service); return kIOReturnNotFound; } notificationContext.info = (void *)¬ificationContext; notificationContext.version = 0; notificationContext.release = NULL; notificationContext.retain = NULL; notificationContext.copyDescription = NULL; // Create a mach port to receive notifications from the kernel notificationPort = CFMachPortCreate(kCFAllocatorDefault, iSCSIKernelNotificationHandler, ¬ificationContext,NULL); IOConnectSetNotificationPort(connection,0,CFMachPortGetPort(notificationPort),0); return IOReturnToErrno(IOConnectCallScalarMethod(connection,kiSCSIOpenInitiator,0,0,0,0)); }
static IOReturn vnodeNotificationHandler(io_connect_t connection) { kern_return_t kr; VnodeWatcherData_t vdata; UInt32 dataSize; IODataQueueMemory *queueMappedMemory; vm_size_t queueMappedMemorySize; vm_address_t address = nil; vm_size_t size = 0; unsigned int msgType = 1; // family-defined port type (arbitrary) mach_port_t recvPort; // allocate a Mach port to receive notifications from the IODataQueue if (!(recvPort = IODataQueueAllocateNotificationPort())) { fprintf(stderr, "%s: failed to allocate notification port\n", PROGNAME); return kIOReturnError; } // this will call registerNotificationPort() inside our user client class kr = IOConnectSetNotificationPort(connection, msgType, recvPort, 0); if (kr != kIOReturnSuccess) { fprintf(stderr, "%s: failed to register notification port (%d)\n", PROGNAME, kr); mach_port_destroy(mach_task_self(), recvPort); return kr; } // this will call clientMemoryForType() inside our user client class kr = IOConnectMapMemory(connection, kIODefaultMemoryType, mach_task_self(), &address, &size, kIOMapAnywhere); if (kr != kIOReturnSuccess) { fprintf(stderr, "%s: failed to map memory (%d)\n", PROGNAME, kr); mach_port_destroy(mach_task_self(), recvPort); return kr; } queueMappedMemory = (IODataQueueMemory *)address; queueMappedMemorySize = size; while (IODataQueueWaitForAvailableData(queueMappedMemory, recvPort) == kIOReturnSuccess) { while (IODataQueueDataAvailable(queueMappedMemory)) { dataSize = sizeof(vdata); kr = IODataQueueDequeue(queueMappedMemory, &vdata, &dataSize); if (kr == kIOReturnSuccess) { if (*(UInt8 *)&vdata == kt_kStopListeningToMessages) goto exit; printf("\"%s\" %s %s %lu(%s) ", vdata.path, vtype_name(vdata.v_type), vtag_name(vdata.v_tag), vdata.pid, vdata.p_comm); action_print(vdata.action, (vdata.v_type & VDIR)); } else fprintf(stderr, "*** error in receiving data (%d)\n", kr); } } exit: kr = IOConnectUnmapMemory(connection, kIODefaultMemoryType, mach_task_self(), address); if (kr != kIOReturnSuccess) fprintf(stderr, "%s: failed to unmap memory (%d)\n", PROGNAME, kr); mach_port_destroy(mach_task_self(), recvPort); return kr; }
IOReturn vnodeNotificationHandler(io_connect_t connection) { kern_return_t kr; DldDriverDataLog vdata; uint32_t dataSize; IODataQueueMemory *queueMappedMemory; vm_size_t queueMappedMemorySize; #if !__LP64__ || defined(IOCONNECT_MAPMEMORY_10_6) vm_address_t address = nil; vm_size_t size = 0; #else mach_vm_address_t address = NULL; mach_vm_size_t size = 0x0; #endif mach_port_t recvPort; // // allocate a Mach port to receive notifications from the IODataQueue // if (!(recvPort = IODataQueueAllocateNotificationPort())) { PRINT_ERROR(("failed to allocate notification port\n")); return kIOReturnError; } // // this will call registerNotificationPort() inside our user client class // kr = IOConnectSetNotificationPort(connection, kt_DldNotifyTypeLog, recvPort, 0); if (kr != kIOReturnSuccess) { PRINT_ERROR(("failed to register notification port (%d)\n", kr)); mach_port_destroy(mach_task_self(), recvPort); return kr; } // // this will call clientMemoryForType() inside our user client class // kr = IOConnectMapMemory( connection, kt_DldNotifyTypeLog, mach_task_self(), &address, &size, kIOMapAnywhere ); if (kr != kIOReturnSuccess) { PRINT_ERROR(("failed to map memory (%d)\n",kr)); mach_port_destroy(mach_task_self(), recvPort); return kr; } queueMappedMemory = (IODataQueueMemory *)address; queueMappedMemorySize = size; printf("before the while loop\n"); //bool first_iteration = true; while( kIOReturnSuccess == IODataQueueWaitForAvailableData(queueMappedMemory, recvPort) ) { //first_iteration = false; //printf("a buffer has been received\n"); while (IODataQueueDataAvailable(queueMappedMemory)) { dataSize = sizeof(vdata); kr = IODataQueueDequeue(queueMappedMemory, &vdata, &dataSize); if (kr == kIOReturnSuccess) { if (*(UInt32 *)&vdata == kt_DldStopListeningToMessages) goto exit; printf( "\"%s\" %s %i(%s) ", vdata.Fsd.path, vtype_name(vdata.Fsd.v_type), (int)vdata.Fsd.pid, vdata.Fsd.p_comm ); if( DLD_KAUTH_SCOPE_VNODE_ID == vdata.Fsd.scopeID ) vnode_action_print(vdata.Fsd.action, (vdata.Fsd.v_type & VDIR)); else fileop_action_print(vdata.Fsd.action, (vdata.Fsd.v_type & VDIR)); } else { PRINT_ERROR(("*** error in receiving data (%d)\n", kr)); } }// end while }// end while exit: kr = IOConnectUnmapMemory( connection, kt_DldNotifyTypeLog, mach_task_self(), address ); if (kr != kIOReturnSuccess){ PRINT_ERROR(("failed to unmap memory (%d)\n", kr)); } mach_port_destroy(mach_task_self(), recvPort); return kr; }