1. 程式人生 > >應用程序與驅動程序客服端方式交互

應用程序與驅動程序客服端方式交互

dex etime link next self 時間 ise elf defaults

技術分享圖片
實現方式是:
3 環通過IOServiceOpen打開連接驅動
0 環在 start 中設置一個與之交互的Client(方式有設置鍵值對或 new一個Client)
3 環:
// UserClientShared.h

//
//  UserClientShared.h
//  UserSpaceClient
//

#include <stdint.h>

typedef struct TimerValue
{
    uint64_t    time;
    uint64_t    timebase;
} TimerValue;

// 用於用戶客戶端方法的控制請求碼
enum TimerRequestCode {
    kTestUserClientStartTimer,
    kTestUserClientStopTimer,
    kTestUserClientGetElapsedTimerTime,
    kTestUserClientGetElapsedTimerValue,
    kTestUserClientDelayForMs,
    kTestUserClientDelayForTime,
    kTestUserClientInstallTimer,

    kTestUserClientMethodCount
};

//main.cpp

//
//  main.c
//  UserSpaceClient
//

#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include "UserClientShared.h"

kern_return_t   StartTimer (io_connect_t connection);
kern_return_t   StopTimer (io_connect_t connection);
kern_return_t   GetElapsedTimerTime (io_connect_t connection, uint32_t* timerTime);
kern_return_t   GetElapsedTimerValue (io_connect_t connection, TimerValue* timerValue);
kern_return_t   DelayForMs (io_connect_t connection, uint32_t milliseconds);
kern_return_t   DelayForTime (io_connect_t connection, const TimerValue* timerValue);

//以下這些控制請求 都會調試驅動中IOUserClient的externalMethod方法(也就是必須實現)
kern_return_t   StartTimer (io_connect_t connection)
{
    //IOConnectCallMethod用於控制請求
    return IOConnectCallMethod(
                               //連接(端口)
                               connection,
                               //控制碼(函數)
                               kTestUserClientStartTimer,
                               //參數
                               NULL, 0, NULL, 0, NULL, NULL, NULL, NULL);
}

kern_return_t   StopTimer (io_connect_t connection)
{
    return IOConnectCallMethod(connection, kTestUserClientStopTimer, NULL, 0, NULL, 0, NULL, NULL, NULL, NULL);
}

kern_return_t   GetElapsedTimerTime (io_connect_t connection, uint32_t* timerTime)
{
    uint64_t        scalarOut[1];
    uint32_t        scalarOutCount;
    kern_return_t   result;

    scalarOutCount = 1;     // 初始化為scalarOut數組的長度
    result = IOConnectCallScalarMethod(connection, kTestUserClientGetElapsedTimerTime, NULL, 0, scalarOut, &scalarOutCount);
    if (result == kIOReturnSuccess)
        *timerTime = (uint32_t)scalarOut[0];

    return result;
}

kern_return_t   GetElapsedTimerValue (io_connect_t connection, TimerValue* timerValue)
{
    size_t  structOutSize;

    structOutSize = sizeof(TimerValue);
    return IOConnectCallStructMethod(connection, kTestUserClientGetElapsedTimerValue, NULL, 0, timerValue, &structOutSize);
}

kern_return_t   DelayForMs (io_connect_t connection, uint32_t milliseconds)
{
    uint64_t        scalarIn[1];

    scalarIn[0] = milliseconds;
    return IOConnectCallScalarMethod(connection, kTestUserClientDelayForMs, scalarIn, 1, NULL, NULL);
}

kern_return_t   DelayForTime (io_connect_t connection, const TimerValue* timerValue)
{
    return IOConnectCallStructMethod(connection, kTestUserClientDelayForTime, timerValue, sizeof(TimerValue), NULL, 0);
}

IONotificationPortRef   gAsyncNotificationPort = NULL;

IONotificationPortRef   MyDriverGetAsyncCompletionPort ()
{
    // If the port has been allocated, return the existing instance
    if (gAsyncNotificationPort != NULL)
        return gAsyncNotificationPort;

    gAsyncNotificationPort = IONotificationPortCreate(kIOMasterPortDefault);
    return gAsyncNotificationPort;
}

kern_return_t   InstallTimer (io_connect_t connection, uint32_t milliseconds, IOAsyncCallback0 timerCallback, void* context)
{
    io_async_ref64_t    asyncRef;
    uint64_t            scalarIn[1];
    //設置回調函數
    asyncRef[kIOAsyncCalloutFuncIndex] = (uint64_t)timerCallback;
    asyncRef[kIOAsyncCalloutRefconIndex] = (uint64_t)context;
    //設置輸入參數
    scalarIn[0] = milliseconds;
    return IOConnectCallAsyncScalarMethod(connection, kTestUserClientInstallTimer, IONotificationPortGetMachPort(gAsyncNotificationPort),
                                          asyncRef, kIOAsyncCalloutCount, scalarIn, 1, NULL, NULL);
}

void DelayCallback (void *refcon, IOReturn result)
{
    printf("DelayCallback - refcon %08x and result %08x\n", (uint32_t)refcon, result);
    if (refcon == (void*)0xdeadbeef)
        CFRunLoopStop(CFRunLoopGetMain());
}

int main (int argc, const char * argv[])
{
    CFDictionaryRef     matchingDict = NULL;
    io_iterator_t       iter = 0;
    io_service_t        service = 0;
    kern_return_t       kr;

    ////創建一個匹配字典,用於查找任意的 USB 設備
    matchingDict = IOServiceMatching("com_osxkernel_driver_IOKitTest");

    //為匹配字典的所有IO註冊表對象創建叠代器
    kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter);
    if (kr != KERN_SUCCESS)
        return -1;

    ////叠代所有匹配的對象
    while ((service = IOIteratorNext(iter)) != 0)
    {
        task_port_t     owningTask = mach_task_self();
        uint32_t        type = 0;
        //就是一個端口
        io_connect_t    driverConnection;
        //建立驅動連接
        //會觸發驅動程序 IOService類中的newUserClient方法實例化一個新的Client對象 驅動中可以不要實現
        //只要設置一個值就好
//        bool com_osxkernel_driver_IOKitTest::start (IOService *provider)
//        {
//            bool res = super::start(provider);
//            setProperty("IOUserClientClass", "com_osxkernel_driver_IOKitTestUserClient");
//            registerService();
//            return res;
//        }
//        virtual IOReturn newUserClient(
        //用戶傳遞的參數
          //task_t owningTask, void * securityID,
//        UInt32 type, OSDictionary * properties,
         //handler返回給調用者
//        IOUserClient ** handler );
//
//        virtual IOReturn newUserClient( task_t owningTask, void * securityID,
//                                       UInt32 type, IOUserClient ** handler );
        kr = IOServiceOpen(
                           //表示希望連接到的驅動程序
                           service,
                           //表示運行的應用程序
                           owningTask,
                           //無符號 32位×××
                           type,
                           //成功後的返回值
                           &driverConnection);
        if (kr == KERN_SUCCESS)
        {
            uint32_t        timerTime;
            TimerValue      timerValue;
            IONotificationPortRef   notificationPort;
            //獲取一個通知端口
            notificationPort = MyDriverGetAsyncCompletionPort();
            if (notificationPort)
            {
                CFRunLoopSourceRef      runLoopSource;
                runLoopSource = IONotificationPortGetRunLoopSource(notificationPort);
                CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);
            }

            kr = StopTimer(driverConnection);
            printf("StopTimer - %08x\n", kr);

            kr = StartTimer(driverConnection);
            printf("StartTimer - %08x\n", kr);

            kr = GetElapsedTimerTime(driverConnection, &timerTime);
            printf("GetElapsedTimerTime - %08x, time %d\n", kr, timerTime);

            kr = DelayForMs(driverConnection, 100);
            printf("DelayForMs - %08x\n", kr);

            kr = GetElapsedTimerTime(driverConnection, &timerTime);
            printf("GetElapsedTimerTime - %08x, time %d\n", kr, timerTime);

            kr = GetElapsedTimerValue(driverConnection, &timerValue);
            printf("GetElapsedTimerValue - %08x, time %lld / %lld\n", kr, timerValue.time, timerValue.timebase);

            timerValue.timebase = 0;
            timerValue.time = 500;
            kr = DelayForTime(driverConnection, &timerValue);
            printf("DelayForTime - %08x\n", kr);

            timerValue.timebase = 1000;
            kr = DelayForTime(driverConnection, &timerValue);
            printf("DelayForTime - %08x\n", kr);

            kr = GetElapsedTimerTime(driverConnection, &timerTime);
            printf("GetElapsedTimerTime - %08x, time %d\n", kr, timerTime);

            kr = StopTimer(driverConnection);
            printf("StopTimer - %08x\n", kr);

            kr = InstallTimer(driverConnection, 10000, DelayCallback, (void*)0xdeadbeef);
            printf("InstallTimer - %08x\n", kr);
            kr = InstallTimer(driverConnection, 5000, DelayCallback, (void*)0xdead0005);
            printf("InstallTimer - %08x\n", kr);
            kr = InstallTimer(driverConnection, 2000, DelayCallback, (void*)0xdead0002);
            printf("InstallTimer - %08x\n", kr);
            kr = InstallTimer(driverConnection, 7000, DelayCallback, (void*)0xdead0007);
            printf("InstallTimer - %08x\n", kr);

            CFRunLoopRun();

            IONotificationPortDestroy(gAsyncNotificationPort);
            gAsyncNotificationPort = NULL;
            //關閉驅動連接
            IOServiceClose(driverConnection);
        }

        IOObjectRelease(service);
    }
    IOObjectRelease(iter);

    return 0;
}

0 環:
//IOKitTestUserClient.h

//
//  IOKitTestUserClient.h
//  IOKitTest
//

#include <IOKit/IOUserClient.h>
#include "IOKitTest.h"
#include "UserClientShared.h"

class com_osxkernel_driver_IOKitTestUserClient : public IOUserClient
{
    OSDeclareDefaultStructors(com_osxkernel_driver_IOKitTestUserClient)

private:
    task_t                              m_task;
    com_osxkernel_driver_IOKitTest*     m_driver;

    bool        m_timerRunning;
    uint64_t    m_timerStartTime;

    static const IOExternalMethodDispatch   sMethods[kTestUserClientMethodCount];

    static IOReturn     sStartTimer (OSObject* target, void* reference, IOExternalMethodArguments* arguments);
    static IOReturn     sStopTimer (OSObject* target, void* reference, IOExternalMethodArguments* arguments);
    static IOReturn     sGetElapsedTimerTime (OSObject* target, void* reference, IOExternalMethodArguments* arguments);
    static IOReturn     sGetElapsedTimerValue (OSObject* target, void* reference, IOExternalMethodArguments* arguments);
    static IOReturn     sDelayForMs (OSObject* target, void* reference, IOExternalMethodArguments* arguments);
    static IOReturn     sDelayForTime (OSObject* target, void* reference, IOExternalMethodArguments* arguments);
    static IOReturn     sInstallTimer (OSObject* target, void* reference, IOExternalMethodArguments* arguments);
    static void         DelayThreadFunc (void *parameter, wait_result_t);

    IOReturn        startTimer ();
    IOReturn        stopTimer ();
    IOReturn        getElapsedTimerTime (uint32_t* timerTime);
    IOReturn        getElapsedTimerValue (TimerValue* timerValue);
    IOReturn        delayForMs (uint32_t milliseconds);
    IOReturn        delayForTime (const TimerValue* timerValue);

public: 
    virtual bool        initWithTask (task_t owningTask, void* securityToken, UInt32 type, OSDictionary* properties);
    virtual IOReturn    clientClose (void);
    virtual IOReturn    clientDied (void);

    virtual bool        start (IOService* provider);
    virtual void        stop (IOService* provider);
    virtual void        free (void);

    virtual IOReturn    externalMethod (
                                        //32位的請求控制碼 指定客戶端應用程序請求的是哪一個操作
                                        uint32_t selector,
                                        //標題及結體體參數
                                        IOExternalMethodArguments* arguments,
                                        //應該調用的類方法
                                        IOExternalMethodDispatch* dispatch = 0, OSObject* target = 0, void* reference = 0);
};

//UserClientShared.h

//
//  UserClientShared.h
//  UserSpaceClient
//

#include <stdint.h>

typedef struct TimerValue
{
    uint64_t    time;
    uint64_t    timebase;
} TimerValue;

// 用於用戶客戶端方法的控制請求碼
enum TimerRequestCode {
    kTestUserClientStartTimer,
    kTestUserClientStopTimer,
    kTestUserClientGetElapsedTimerTime,
    kTestUserClientGetElapsedTimerValue,
    kTestUserClientDelayForMs,
    kTestUserClientDelayForTime,
    kTestUserClientInstallTimer,

    kTestUserClientMethodCount
};

IOKitTestUserClient.cpp

//
//  IOKitTestUserClient.cpp
//  IOKitTest
//

#include <IOKit/IOLib.h>
#include "IOKitTestUserClient.h"

#define super IOUserClient

OSDefineMetaClassAndStructors(com_osxkernel_driver_IOKitTestUserClient, IOUserClient)

bool    com_osxkernel_driver_IOKitTestUserClient::initWithTask (task_t owningTask, void* securityToken, UInt32 type, OSDictionary* properties)
{
    if (!owningTask)
        return false;
    if (! super::initWithTask(owningTask, securityToken , type, properties))
        return false;

    m_task = owningTask;
    //判斷進程的權限
    IOReturn ret = clientHasPrivilege(securityToken, kIOClientPrivilegeAdministrator);
    if ( ret == kIOReturnSuccess )
    {
        // m_taskIsAdmin = true;
    }

    return true;
}

bool    com_osxkernel_driver_IOKitTestUserClient::start (IOService* provider)
{
    if (! super::start(provider))
        return false;

    m_driver = OSDynamicCast(com_osxkernel_driver_IOKitTest, provider);
    if (!m_driver)
        return false;

    return true;
}

void    com_osxkernel_driver_IOKitTestUserClient::stop (IOService* provider)
{
    IOLog("userClient::stop\n");
    super::stop(provider);
}

void    com_osxkernel_driver_IOKitTestUserClient::free (void)
{
    IOLog("userClient::free\n");
    super::free();
}

IOReturn    com_osxkernel_driver_IOKitTestUserClient::clientClose (void)
{
    terminate();
    return kIOReturnSuccess;
}

IOReturn    com_osxkernel_driver_IOKitTestUserClient::clientDied (void)
{
    IOLog("userClient::clientDied\n");
    return super::clientDied();
}

IOReturn    com_osxkernel_driver_IOKitTestUserClient::sStartTimer (OSObject* target, void* reference, IOExternalMethodArguments* arguments)
{
    com_osxkernel_driver_IOKitTestUserClient*   me = (com_osxkernel_driver_IOKitTestUserClient*)target;

    return me->startTimer();
}

IOReturn    com_osxkernel_driver_IOKitTestUserClient::sStopTimer (OSObject* target, void* reference, IOExternalMethodArguments* arguments)
{
    com_osxkernel_driver_IOKitTestUserClient*   me = (com_osxkernel_driver_IOKitTestUserClient*)target;

    return me->stopTimer();
}

IOReturn    com_osxkernel_driver_IOKitTestUserClient::sGetElapsedTimerTime (OSObject* target, void* reference, IOExternalMethodArguments* arguments)
{
    com_osxkernel_driver_IOKitTestUserClient*   me = (com_osxkernel_driver_IOKitTestUserClient*)target;
    uint32_t        timerTime;
    IOReturn        result;
    //調用實現操作的方法
    result = me->getElapsedTimerTime(&timerTime);
    //將操作的標量結果返回給調用進程
    arguments->scalarOutput[0] = timerTime;

    return result;
}

IOReturn    com_osxkernel_driver_IOKitTestUserClient::sGetElapsedTimerValue (OSObject* target, void* reference, IOExternalMethodArguments* arguments)
{
    com_osxkernel_driver_IOKitTestUserClient*   me = (com_osxkernel_driver_IOKitTestUserClient*)target;

    return me->getElapsedTimerValue((TimerValue*)arguments->structureOutput);
}

IOReturn    com_osxkernel_driver_IOKitTestUserClient::sDelayForMs (OSObject* target, void* reference, IOExternalMethodArguments* arguments)
{
    com_osxkernel_driver_IOKitTestUserClient*   me = (com_osxkernel_driver_IOKitTestUserClient*)target;

    return me->delayForMs((uint32_t)arguments->scalarInput[0]);
}

IOReturn    com_osxkernel_driver_IOKitTestUserClient::sDelayForTime (OSObject* target, void* reference, IOExternalMethodArguments* arguments)
{
    com_osxkernel_driver_IOKitTestUserClient*   me = (com_osxkernel_driver_IOKitTestUserClient*)target;

    return me->delayForTime((TimerValue*)arguments->structureInput);
}

//保存後臺操作所需參數的結構體
struct TimerParams
{
    OSAsyncReference64      asyncRef;
    uint32_t                milliseconds;
    OSObject*               userClient;
};

IOReturn    com_osxkernel_driver_IOKitTestUserClient::sInstallTimer (OSObject* target, void* reference, IOExternalMethodArguments* arguments)
{
    TimerParams*    timerParams;
    thread_t        newThread;

    //分配一個結構體,存儲定時器需要的參數
    timerParams = (TimerParams*)IOMalloc(sizeof(TimerParams));
    //取得asyncReference緩沖區的一個副本
    bcopy(arguments->asyncReference, timerParams->asyncRef, sizeof(OSAsyncReference64));
    //取得用戶應用程序提供的milliseconds值的一個副本
    timerParams->milliseconds = (uint32_t)arguments->scalarInput[0];
    //取得userClient對象的一個引用
    timerParams->userClient = target;
    //異步操作執行時,保留該用戶客戶端
    target->retain();

    //啟動一個後臺線程,在返回給調用者之後繼續執行操作
    kernel_thread_start(DelayThreadFunc, timerParams, &newThread);
    thread_deallocate(newThread);

    //立即返回給調用應用程序
    return kIOReturnSuccess;
}

void    com_osxkernel_driver_IOKitTestUserClient::DelayThreadFunc (void *parameter, wait_result_t)
{
    TimerParams*    timerParams = (TimerParams*)parameter;

    //按請求的時間睡眠
    IOSleep(timerParams->milliseconds);
    //向用戶應用程序發送操作完成的通知
    sendAsyncResult64(timerParams->asyncRef, kIOReturnSuccess, NULL, 0);

    //後臺操作已經完成
    timerParams->userClient->release();

    IOFree(timerParams, sizeof(TimerParams));
}

IOReturn    com_osxkernel_driver_IOKitTestUserClient::startTimer ()
{
    if (m_timerRunning == true)
        return kIOReturnBusy;

    m_timerRunning = true;
    clock_get_uptime(&m_timerStartTime);

    return kIOReturnSuccess;
}

IOReturn    com_osxkernel_driver_IOKitTestUserClient::stopTimer ()
{
    if (m_timerRunning == false)
        return kIOReturnNotOpen;

    m_timerRunning = false;
    return kIOReturnSuccess;
}

IOReturn    com_osxkernel_driver_IOKitTestUserClient::getElapsedTimerTime (uint32_t* timerTime)
{
    uint64_t    timeNow;
    uint64_t    elapsedTime;

    if (m_timerRunning == false)
        return kIOReturnNotOpen;

    clock_get_uptime(&timeNow);
    absolutetime_to_nanoseconds((timeNow - m_timerStartTime), &elapsedTime);
    *timerTime = (uint32_t)(elapsedTime / 1000000);

    return kIOReturnSuccess;
}

IOReturn    com_osxkernel_driver_IOKitTestUserClient::getElapsedTimerValue (TimerValue* timerValue)
{
    uint64_t    timeNow;
    uint64_t    elapsedTime;

    if (m_timerRunning == false)
        return kIOReturnNotOpen;

    clock_get_uptime(&timeNow);
    absolutetime_to_nanoseconds((timeNow - m_timerStartTime), &elapsedTime);
    timerValue->timebase = 1000000;
    timerValue->time = (elapsedTime * timerValue->timebase) / 1000000000;

    return kIOReturnSuccess;
}

IOReturn    com_osxkernel_driver_IOKitTestUserClient::delayForMs (uint32_t milliseconds)
{
    IOSleep(milliseconds);
    return kIOReturnSuccess;
}

IOReturn    com_osxkernel_driver_IOKitTestUserClient::delayForTime (const TimerValue* timerValue)
{
    uint32_t        milliseconds;

    if (timerValue->timebase == 0)
        return kIOReturnBadArgument;

    milliseconds = (uint32_t)((timerValue->time * 1000) / timerValue->timebase);
    IOSleep(milliseconds);

    return kIOReturnSuccess;
}

//調試表
const IOExternalMethodDispatch com_osxkernel_driver_IOKitTestUserClient::sMethods[kTestUserClientMethodCount] =
{
    // kTestUserClientStartTimer   (void)
    { sStartTimer, 0, 0, 0, 0 },

    // kTestUserClientStopTimer   (void)
    { sStopTimer, 0, 0, 0, 0 },

    // kTestUserClientGetElapsedTimerTime   (uint32_t* timerValue)
    { sGetElapsedTimerTime, 0, 0, 1, 0 },

    // kTestUserClientGetElapsedTimerValue   (TimerValue* timerValue)
    { sGetElapsedTimerValue, 0, 0, 0, sizeof(TimerValue) },

    // kTestUserClientDelayForMs   (uint32_t milliseconds)
    { sDelayForMs, 1, 0, 0, 0 },

    // kTestUserClientDelayForTime  (const TimerValue* timerValue)
    { sDelayForTime, 0, sizeof(TimerValue), 0, 0 },

    // kTestUserClientInstallTimer  (uint32_t milliseconds)
    { sInstallTimer, 1, 0, 0, 0 }
};
//驅動程序的IOUserClient子類提供的實現
IOReturn    com_osxkernel_driver_IOKitTestUserClient::externalMethod (uint32_t selector, IOExternalMethodArguments* arguments,
                                    IOExternalMethodDispatch* dispatch, OSObject* target, void* reference)
{
    //判斷控制碼 確保請求的控制碼選擇器在範圍內
    if (selector >= kTestUserClientMethodCount)
        return kIOReturnUnsupported;
    //選擇相應的控制碼(也就是調試表)
    dispatch = (IOExternalMethodDispatch*)&sMethods[selector];
    target = this;
    reference = NULL;
    //返回父類的
    return super::externalMethod(selector, arguments, dispatch, target, reference);
    //超類的實現
//    externalMethod(selector, arguments, dispatch, target, reference){
//        Dispatch->function(target,reference,args);
//    }
}

//IOKitTest.h

#include <IOKit/IOService.h>

class com_osxkernel_driver_IOKitTest : public IOService
{
    OSDeclareDefaultStructors(com_osxkernel_driver_IOKitTest)

public: 
    virtual bool        init (OSDictionary* dictionary = NULL);
    virtual void        free (void);

    virtual bool        start (IOService* provider);
    virtual void        stop (IOService* provider);
};

//IOKitTest.cpp

        #include "IOKitTest.h"
#include <IOKit/IOLib.h>

#define super IOService

OSDefineMetaClassAndStructors(com_osxkernel_driver_IOKitTest, IOService)

bool com_osxkernel_driver_IOKitTest::init (OSDictionary* dict)
{
    bool res = super::init(dict);
    return res;
}

void com_osxkernel_driver_IOKitTest::free (void)
{
    super::free();
}
//啟動時設置與之交互的IOUserClientClass
bool com_osxkernel_driver_IOKitTest::start (IOService *provider)
{
    bool res = super::start(provider);
    setProperty("IOUserClientClass", "com_osxkernel_driver_IOKitTestUserClient");
    registerService();
    return res;
}

void com_osxkernel_driver_IOKitTest::stop (IOService *provider)
{
    super::stop(provider);
}
liuhailongdeMacBook-Air:~ liuhailong$ sudo chown -R root:wheel /Users/liuhailong/Library/Developer/Xcode/DerivedData/IOKitTest-dpmmsjcydkpiyxewowmltvnxxxgh/Build/Products/Debug/IOKitTest.kext 
liuhailongdeMacBook-Air:~ liuhailong$  sudo kextload /Users/liuhailong/Library/Developer/Xcode/DerivedData/IOKitTest-dpmmsjcydkpiyxewowmltvnxxxgh/Build/Products/Debug/IOKitTest.kext 
/Users/liuhailong/Library/Developer/Xcode/DerivedData/IOKitTest-dpmmsjcydkpiyxewowmltvnxxxgh/Build/Products/Debug/IOKitTest.kext failed to load - (libkern/kext) link error; check the system/kernel logs for errors or try kextutil(8).
liuhailongdeMacBook-Air:~ liuhailong$ sudo chown -R root:wheel /Users/liuhailong/Library/Developer/Xcode/DerivedData/IOKitTest-dpmmsjcydkpiyxewowmltvnxxxgh/Build/Products/Debug/IOKitTest.kext 
liuhailongdeMacBook-Air:~ liuhailong$  sudo kextload /Users/liuhailong/Library/Developer/Xcode/DerivedData/IOKitTest-dpmmsjcydkpiyxewowmltvnxxxgh/Build/Products/Debug/IOKitTest.kext 
liuhailongdeMacBook-Air:~ liuhailong$ /Users/liuhailong/Library/Developer/Xcode/DerivedData/UserSpaceClient-ffozqcnbwexasqelqqgpccijiicg/Build/Products/Debug/UserSpaceClient 
StopTimer - e00002cd
StartTimer - 00000000
GetElapsedTimerTime - 00000000, time 0
DelayForMs - 00000000
GetElapsedTimerTime - 00000000, time 100
GetElapsedTimerValue - 00000000, time 100170 / 1000000
DelayForTime - e00002c2
DelayForTime - 00000000
GetElapsedTimerTime - 00000000, time 600
StopTimer - 00000000
InstallTimer - 00000000
InstallTimer - 00000000
InstallTimer - 00000000
InstallTimer - 00000000
DelayCallback - refcon dead0002 and result 00000000
DelayCallback - refcon dead0005 and result 00000000
DelayCallback - refcon dead0007 and result 00000000
DelayCallback - refcon deadbeef and result 00000000
liuhailongdeMacBook-Air:~ liuhailong$ 

技術分享圖片

應用程序與驅動程序客服端方式交互