C/C++知识点之应用程序与驱动程序客服端方式交互
小标 2019-03-14 来源 : 阅读 773 评论 0

摘要:本文主要向大家介绍了C/C++知识点之应用程序与驱动程序客服端方式交互,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

本文主要向大家介绍了C/C++知识点之应用程序与驱动程序客服端方式交互,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

C/C++知识点之应用程序与驱动程序客服端方式交互

实现方式是:
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 IOUserClientOSDefineMetaClassAndStructors(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

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程