您的位置:首页 > 其它

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

2010-03-03 16:56 459 查看
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

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

欢迎转载,转载请指明源出处。谢谢
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: