深入剖析wince6.0下kernelIOctl()的调用过程分析

来源:互联网 发布:网络信息化工程公司 编辑:程序博客网 时间:2024/05/17 17:43

wince6.0下kernelIOctl()的调用过程分析
一初始化部分:
1.LoaderInit() //:private/winceos/coreos/nk/kernel/loader.c
{
.........
 // load OAL ioctl dll; this is valid only if image has coredll
        LockLoader (g_pprcNK);
        if (pMod = LoadOneLibrary (OALIOCTL_DLL, 0, LOAD_LIBRARY_IN_KERNEL)) {
            pMod = (*g_pfnDoImports) (pMod);
            VERIFY (g_pfnOalIoctl = (PFN_Ioctl) GetProcAddressA ((HMODULE)pMod, OALIOCTL_DLL_IOCONTROL));
     /*************************************************************************************************
     上条语句是将OALIOCTL_DLL文件里的IOCONTROL函数的地址
     赋(D:/WINCE600/PLATFORM/seeker2/SRC/COMMON/OALIOCTL/oalioctl.cpp里的IOControl)给g_pfnOalIoctl
            *************************************************************************************************/
            VERIFY (((PFN_DllMain) pMod->startip) ((HMODULE)pMod, DLL_PROCESS_ATTACH, (DWORD) &(OEMIoControl)));
            /**************************************************************************************************
     上条语句是将调用OALIOCTL_DLL库的DLLmain函数,由此对该库的全局变量初始化:
            ****************************************************************************************************/         
        }
.......... 

}
2.DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
{
    switch (dwReason)
    {
        case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCalls((HINSTANCE)hDll);
            g_pfnExtOALIoctl = (PFN_Ioctl) lpReserved;//该库的全局变量初始化,也就是OEMIoControl函数地址
        break;
        case DLL_PROCESS_DETACH:
        default:
        break;
    }

    return TRUE;
}
二.执行过程:

  kernelIOcontrol()   //EXTkernelIoctl()函数为其内核中的实现函数,
             |
             |
             |
     IOConTrol()      //seeker2/src/common/oalioctl/oalioctl.cpp
             |
             |
             |
     OEMIOControl()   //platform/common/src/common/ioctl/ioctl.c

             |

             |

             |

     ioctrolFUN //自己定义的ioctro函数,在g_oalIoCtlTable[]添加该函数与其ioctrol宏的映射。

1.EXTKernelIoctl的实现
  static BOOL EXTKernelIoctl (DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize, LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned)
{
    BOOL fRet = FALSE;
    PPROCESS pprc = SwitchActiveProcess (g_pprcNK);
   
    switch (dwIoControlCode) {
        // KITL ioctls
        case IOCTL_EDBG_REGISTER_CLIENT:
        case IOCTL_EDBG_DEREGISTER_CLIENT:
        case IOCTL_EDBG_REGISTER_DFLT_CLIENT:
        case IOCTL_EDBG_SEND:
        case IOCTL_EDBG_RECV:
        case IOCTL_EDBG_SET_DEBUG:       
            fRet = (g_pfnExtKITLIoctl) ?
                   (*g_pfnExtKITLIoctl) (dwIoControlCode, lpInBuf, nInBufSize, lpOutBuf, nOutBufSize, lpBytesReturned)
                   : FALSE;
        break;
      
        default:
            // OEM ioctls
            fRet = (g_pfnOalIoctl) ?
                   (*g_pfnOalIoctl)(dwIoControlCode, lpInBuf, nInBufSize, lpOutBuf, nOutBufSize, lpBytesReturned)
                   : FALSE;  
          //调用OALIOCTL_DLL库IOControl函数
        break;
    }
    SwitchActiveProcess (pprc); 
    return fRet;
}
 2.IOControl()的实现
   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_POCKETSTOREII_CMD:
        case IOCTL_HAL_POSTINIT:
            // request is to service the ioctl - forward the call to OAL code
            // OAL code will set the last error if there is a failure
            SetLastError(ERROR_NOT_SUPPORTED); //注意这里是我们自己项目BSP中该函数的代码,主要为了简化ioctl,所以和D:/WINCE600/PUBLIC/COMMON/OAK/OALIOCTL/oalioctl.cpp代码,刚好相反,
                                                //但这样做,比较方便我们添加ioctrol,但给安全,不推荐。开个的权限太大了。呵呵
        break;
        default:
            fRet = (*g_pfnExtOALIoctl)(dwIoControlCode, pInBuf, nInBufSize, pOutBuf, nOutBufSize, pBytesReturned);
        break;
    }

    return fRet;
3.OEMIOControl()的实现 ,D:/WINCE600/PLATFORM/COMMON/SRC/COMMON/IOCTL/ioctl.c

//这个函数去逐个查找你所定义的ioctrol的宏和对应的处理函数,然后去执行。

//  Function:  OEMIoControl
//
//  The function is called by kernel a device driver or application calls
//  KernelIoControl. The system is fully preemtible when this function is
//  called. The kernel does no processing of this API. It is provided to
//  allow an OEM device driver to communicate with kernel mode code.
//
BOOL OEMIoControl(
    DWORD code, VOID *pInBuffer, DWORD inSize, VOID *pOutBuffer, DWORD outSize,
    DWORD *pOutSize
) {
    BOOL rc = FALSE;
    UINT32 i;

    OALMSG(OAL_IOCTL&&OAL_FUNC, (
        L"+OEMIoControl(0x%x, 0x%x, %d, 0x%x, %d, 0x%x)/r/n",
        code, pInBuffer, inSize, pOutBuffer, outSize, pOutSize
    ));

    //Initialize g_ioctlState.cs when IOCTL_HAL_POSTINIT is called. By this time,
    //the kernel is up and ready to handle the critical section initialization.
    if (!g_ioctlState.postInit && code == IOCTL_HAL_POSTINIT) {
        // Initialize critical section
        InitializeCriticalSection(&g_ioctlState.cs);
        g_ioctlState.postInit = TRUE;
    }

    // Search the IOCTL table for the requested code.
    for (i = 0; g_oalIoCtlTable[i].pfnHandler != NULL; i++) {
        if (g_oalIoCtlTable[i].code == code) break;
    }

    // Indicate unsupported code
    if (g_oalIoCtlTable[i].pfnHandler == NULL) {
        NKSetLastError(ERROR_NOT_SUPPORTED);
        OALMSG(OAL_IOCTL, (
            L"OEMIoControl: Unsupported Code 0x%x - device 0x%04x func %d/r/n",
            code, code >> 16, (code >> 2)&0x0FFF
        ));
        goto cleanUp;
    }       

    // Take critical section if required (after postinit & no flag)
    if (
        g_ioctlState.postInit &&
        (g_oalIoCtlTable[i].flags & OAL_IOCTL_FLAG_NOCS) == 0
    ) {
        // Take critical section           
        EnterCriticalSection(&g_ioctlState.cs);
    }

    // Execute the handler
    rc = g_oalIoCtlTable[i].pfnHandler(
        code, pInBuffer, inSize, pOutBuffer, outSize, pOutSize
    );

    // Release critical section if it was taken above
    if (
        g_ioctlState.postInit &&
        (g_oalIoCtlTable[i].flags & OAL_IOCTL_FLAG_NOCS) == 0
    ) {
        // Release critical section           
        LeaveCriticalSection(&g_ioctlState.cs);
    }

cleanUp:
    OALMSG(OAL_IOCTL&&OAL_FUNC, (L"-OEMIoControl(rc = %d)/r/n", rc ));
    return rc;
}

http://blog.csdn.net/bbw2008/archive/2010/03/03/5342837.aspx

如果有什么理解错误的地方,欢迎各位看客不吝赐教。在此谢谢了。

欢迎转载,转载请指明源出处。谢谢

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/bbw2008/archive/2010/03/03/5342837.aspx

原创粉丝点击