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; }