摘要:本文主要向大家介绍了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+频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号