在WinCE5.0中,應用程序和驅動程序可以通過調用KernelIoControl(..)函數來訪問WinCE內核,導致調用 OEMIoControl函數,這樣應用程序和驅動程序就可以訪問到OAL中的資源了。但在WinCE6.0中,提供了更好的安全性,應用程序能夠訪問 OEMIoControl中的case受到了限制,默認情況下只有下面的這些case是可以讓應用程序訪問的:
IOCTL_HAL_GET_CACHE_INFO
IOCTL_HAL_GET_DEVICE_INFO
IOCTL_HAL_GET_DEVICEID
IOCTL_HAL_GET_UUID
IOCTL_PROCESSOR_INFORMATION
如果用戶在應用程序中試圖訪問其他的case,肯定會返回失敗的。在WinCE6.0中,驅動程序還像以前一樣,可以訪問OEMIoControl中的任何 case。那麼我們如何讓應用程序也訪問到一些自己添加的case呢?以下以我IOCTL_HAL_GET_MAP_CODE爲例,詳細講解如何添加自定義的case給應用程序調用:
1. %(_WINCEROOT)/PUBLIC/COMMON/OAK/INC/pkfuncs.h 添加要設置的IOCTL:
#define IOCTL_SET_KERNEL_COMM_DEV CTL_CODE(FILE_DEVICE_HAL, 12, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_HAL_GET_UUID CTL_CODE(FILE_DEVICE_HAL, 13, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_HAL_GET_MAP_CODE CTL_CODE(FILE_DEVICE_HAL,2075,METHOD_BUFFERED,FILE_ANY_ACCESS)
2. 到OAL 層的oalioctl.cpp 裏添加我們定義的IOCTL :
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_HAL_GET_MAP_CODE: //Andy
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;
}
這些IOCTL 都是應用程序可以調用的;
3.%(_WINCEROOT)/PLATFORM/COMMON/SRC/INC/oal_ioctl_tab.h 添加 IOCTL 對應的函數:
{ IOCTL_HAL_GET_MAP_CODE, 0, OALIoCtlHalGetMapCode }, //Andy
4. %(_WINCEROOT)/PLATFORM/COMMON/SRC/INC/oal_ioctl.h 添加函數聲明:
BOOL OALIoCtlHalGetMapCode(UINT32, VOID *, UINT32, VOID *, UINT32, UINT32 *); //Andy
5. %(_WINCEROOT)/PLATFORM/COMMON/SRC/COMMON/IOCTL/mapcode.c 添加函數定義:
//------------------------------------------------------------------------------
//
// Function: OALIoCtlHalGetMapCode
//
// Implements the IOCTL_HAL_GET_MAP_CODE handler. This function fills in a
// GUID structure.
//
BOOL OALIoCtlHalGetMapCode(
UINT32 code,
VOID *pInpBuffer,
UINT32 inpSize,
VOID *pOutBuffer,
UINT32 outSize,
UINT32 *pOutSize
)
{
…(具體實現省略)
return rc;
}
這樣就完成了該功能的添加。
(聲明:該文章是在網絡相關文章的基礎上,修改了錯誤,更換了示例而成。因原文章被抄來抄去,已經沒辦法找到原著者,因此,此處沒辦法表明,請諒解。)