예제 #1
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;
}