WinCE6下的kernelIoControl使用方法

时间:2022-03-27 07:33:47

WinCE6下的kernelIoControl可不是谁都可以调的。

这个可能很多人曾经知道,但是老是忘记,比如我,哈哈。

kerneliocontrol以前在CE5下面耍惯了,用这个接口,AP简直可以无法无天啊,动不动就reset你,哼!who怕who(AP不要 kernelicontrol还是可以无法无天,fullkernel啊,哈哈)

最近加了一个CE6下的kerneliocontrol,这种事情不晓得做过多少啦,所以信手拈来。

1.加IOCTL的code定义

2.加ioctl_tab.h里面的table里面code和function的关联

3.加ioctl.c里面function的实现。

4.在AP里面调用kerneliocontrol,参数是code,试图访问这个function

结果发现,AP每次调用kerneliocontrol都是fail,但是参数全部正确啊,晕。

NND,毛了,在function里面加了一堆debug信息,重新出image,哼看你出不出来!

结果发现,压根没进function。

晕again!第一反应是哪里没有加全或者有代码修改了但是build不到位。

check了n遍,还是不行,开始怀疑自己老年痴呆了!?

迷茫中突然想到CE6之前不是有篇文章说过,AP不能随便调用kerneliocontrol的。

逐翻出此文。发现果然有门道在其中,但是那篇文章不够详细,没有告诉我怎么才能改变权限。

翻了翻BSP(CSP),果然找到真的有那么一个地方来决定哪些IOCTL的code是允许被AP call的。

PFN_Ioctl g_pfnExtOALIoctl;

//------------------------------------------------------------------------------

// Function: IOControl

//

// Arguments: Same signature as KernelIoControl

//    DWORD dwIoControlCode: io control code

//    PBYTE pInBuf: pointer to input buffer

//    DWORD nInBufSize: length of input buffer in bytes

//    PBYTE pOutBuf: pointer to out buffer

//    DWORD nOutBufSize: length of output buffer in bytes

//    PDWORD pBytesReturned: number of bytes returned in output buffer

//

// Return Values:

// If the function call is successful, TRUE is returned from this API call.

// If the function call is not successful, FALSE is returned from this API

// call and the last error is set to:

// a) ERROR_INVALID_PARAMETER: any of the input arguments are invalid

// b) ERROR_NOT_SUPPORTED: given ioctl is not supported

// c) any other ioctl set by OAL code

//

// Abstract:

// This is called by kernel whenever a user mode thread makes a call to

// KernelIoControl or KernelLibIoControl with io control code being an OAL

// io control code. OEMs can override what ioctls a user mode thread can call

// by enabling or disabling ioctl codes in this function.

//

//------------------------------------------------------------------------------

EXTERN_C

BOOL

IOControl(

    DWORD dwIoControlCode,

    PBYTE pInBuf,

    DWORD nInBufSize,

    PBYTE pOutBuf,

    DWORD nOutBufSize,

    PDWORD pBytesReturned

)

{

    BOOL fRet = FALSE;

    //

    // By default the following ioctls are supported for user mode threads.

    // If a new ioctl is being added to this list, make sure the corresponding

    // data associated with that ioctl is marshalled properly to the OAL

    // ioctl implementation. In normal cases, one doesn't need any

    // marshaling as first level user specified buffers are already validated

    // by kernel that:

    // -- the buffers are within the user process space

    // Check out IsValidUsrPtr() function in vmlayout.h for details on kernel

    // validation of user specified buffers. Kernel doesn't validate that the

    // buffers are accessible; it only checks that the buffer start and end

    // addresses are within the user process space.

    //

 

    switch (dwIoControlCode)

    {

        case IOCTL_HAL_GET_CACHE_INFO:

        case IOCTL_HAL_GET_DEVICE_INFO:

        case IOCTL_HAL_GET_DEVICEID:

        case IOCTL_HAL_GET_UUID:

        case IOCTL_PROCESSOR_INFORMATION:

        case IOCTL_SET_RTC_WAKEUP_TIME:

        case IOCTL_HAL_GET_SYS_CLOCK_INFO:

        case IOCTL_HAL_GET_BTMACADDR:

        case IOCTL_HAL_GET_CUSTOMERNUM:

        case IOCTL_HAL_GET_FURTURENUM:

        case IOCTL_HAL_GET_OEMVALUE:

        case IOCTL_HAL_REBOOT:

            // request is to service the ioctl - forward the call to OAL code

            // OAL code will set the last error if there is a failure

            fRet = (*g_pfnExtOALIoctl)(dwIoControlCode, pInBuf, nInBufSize, pOutBuf, nOutBufSize, pBytesReturned);

            break;

        default:

            SetLastError(ERROR_NOT_SUPPORTED);

            break;

    }

    return fRet;

}

在 case里面的IOCTL是运行被AP调用的,比如上面的 IOCTL_HAL_REBOOT。

里面还有一段英文注释,意思大概是,AP调用的kerneliocontrol都会先到这里来集合,通过这里的switch case决定是否允许调用到正真的function.只要把你的IOCTL的code加到case里面,它才能被上层AP访问。

kernel模式的驱动要call kerneliocontrol的话应该是直接调用到真正的ioctl,不需要跑到这个鬼地方来.