示例#1
0
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 *)&notificationContext;
    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,
                                        &notificationContext,NULL);
    IOConnectSetNotificationPort(connection,0,CFMachPortGetPort(notificationPort),0);
    

    return IOReturnToErrno(IOConnectCallScalarMethod(connection,kiSCSIOpenInitiator,0,0,0,0));
}
示例#3
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;
}