订制自己的KernelIoControl

本文深入解析了KernelIoControl函数的工作原理及其在系统重启等操作中的应用。介绍了如何自定义IOControl指令,包括定义控制码、配置处理表及实现具体功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

KernelIoControl无论是在驱动开发,还是应用程序中,我们都会用到各种各样的IOControl指令,去完成相关的操作.

eg.

       KernelIoControl(IOCTL_HAL_REBOOT, NULL, 0, NULL, 0, NULL);

这行代码完成了系统WarmBoot的功能,我们无法看到KernelIoControl的具体实现,从Windows Mobile 6 Document中,看得出来该函数会最终调用OEMIoControl,我们可以从这个函数入手。

The kernel calls the OEMIoControl function when adevice driver or application calls the kernel function KernelIoControl and passesan I/O control code.

 

PrototypeOf KernelIoControl

BOOL KernelIoControl(

  DWORD dwIoControlCode,

  LPVOID lpInBuf,

  DWORD nInBufSize,

  LPVOID lpOutBuf,

  DWORD nOutBufSize,

  LPDWORD lpBytesReturned

);

RequirementsOf KernelIoControl

Header

pkfuncs.h

Library

coredll.lib

Windows Mobile

Windows Mobile Version 5.0 and later

上述涉及到的两个文件的存放路径如下:

WM613\PUBLIC\COMMON\OAK\INC\pkfuncs.h

WM613\PUBLIC\COMMON\OAK\LIB\ARMV4I\RETAIL\coredll.lib

OEMIoControl该函数用来Driver LayerKernel进行通讯的,当应用层调用KernelIoControl时,该函数会最终被调用,或者Driver Layer可以直接调用它。

\WM613\PLATFORM\COMMON\SRC\COMMON\IOCTL\ioctl.c

该函数的功能主要就是在g_oalIoCtlTable查找目标函数,并执行。

       // Search the IOCTL table for the requestedcode.

    for (i = 0; g_oalIoCtlTable[i].pfnHandler!= NULL; i++) {

        if (g_oalIoCtlTable[i].code == code)break;

}

// Execute the handler

rc = g_oalIoCtlTable[i].pfnHandler(

  code, pInBuffer, inSize, pOutBuffer, outSize, pOutSize

);

 

查找的依据是g_oalIoCtlTable[i].codeeg.IOCTL_HAL_REBOOT(phfuncs.h中定义)

g_oalIoCtlTableioctl.c中定义。

SMDK6410\Src\Kernel\Oal\ioctl.c

const OAL_IOCTL_HANDLERg_oalIoCtlTable[] = {

#include "ioctl_tab.h"

};

在浏览ioctl_tab.h的内容之前,我们先看一下OAL_IOCTL_HANDLER结构体的定义。

typedef struct {

   UINT32  code;

   UINT32  flags;

   BOOL    (*pfnHandler)(UINT32,VOID*, UINT32, VOID*, UINT32, UINT32*);

} OAL_IOCTL_HANDLER,*POAL_IOCTL_HANDLER

就是通过code来查找目标函数的,SMDK6410\Src\Inc\ioctl_tab.h中的内容如下:

{ IOCTL_HAL_INITREGISTRY,                   0,  OALIoCtlHalInitRegistry     },

{ IOCTL_HAL_INIT_RTC,                      0,  OALIoCtlHalInitRTC          },

{ IOCTL_HAL_REBOOT,                       0,  OALIoCtlHalReboot           },

{ IOCTL_HAL_PRE_POWEROFF,                                  0, OALIoCtlHalPrePowerOff      }

OALIoCtlHalReboot的实体在SMDK6410\Src\Kernel\Oal\ioctl.c中定义。

static BOOL OALIoCtlHalReboot(

                   UINT32code, VOID *pInpBuffer, UINT32 inpSize,

                   VOID*pOutBuffer, UINT32 outSize, UINT32 *pOutSize)

{

OALMSG(OAL_IOCTL&&OAL_FUNC,(TEXT("[OAL] ++OALIoCtlHalReboot()\r\n")));

OEMSWReset();

OALMSG(OAL_IOCTL&&OAL_FUNC,(TEXT("[OAL] --OALIoCtlHalReboot()\r\n")));

Return TRUE;

}

 

UserDefined如何定义自己的IOControl呢?从上面的分析来看,主要分三个步骤:

FirstStep定义控制码,<phfuncs.h, ioctl_cfg.h,oal_ioctl.h或者其他的,只要能被Application, DriverAnd Kernel看到即可>,我选择了ioctl_cfg.h

#defineIOCTL_HAL_PRE_POWEROFF        CTL_CODE(FILE_DEVICE_HAL,     2123, METHOD_BUFFERED, FILE_ANY_ACCESS)

注意红色标注的部分,Note that functioncodes 0-2047 are reserved for Microsoft Corporation, and 2048-4095 are reservedfor customers.

SencondStep:配置g_oalIoCtlTable。在ioctl_tab.h中添加。

{ IOCTL_HAL_PRE_POWEROFF,                    0, OALIoCtlHalPrePowerOff      }

LastStep:实现OALIoCtlHalPrePowerOff,SMDK6410\Src\Kernel\Oal\ioctl.c中定义即可,当然也可以自由选择,调用的时候能找到就行。

static BOOLOALIoCtlHalPrePowerOff(

UINT32 code, VOID*pInpBuffer, UINT32 inpSize,

VOID *pOutBuffer, UINT32outSize, UINT32 *pOutSize)

{

BOOL bFlag= FALSE;

if(inpSize == 0 ||!pInpBuffer)

{

         return FALSE;

}

 

bFlag = *(BOOL*)pInpBuffer;

OEMPrePowerOff(bFlag);

 

return TRUE;

}

 

这样你就可以在Application Layer或者Driver Layer调用该函数了。

KernelIoControl(IOCTL_HAL_PRE_POWEROFF,&bPowerOff, sizeof(BOOL), NULL, 0, NULL)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值