對(duì)于KernelIoControl這個(gè)函數(shù)我們并不陌生,在2440 5.0BSP當(dāng)中,這個(gè)函數(shù)在很多驅(qū)動(dòng)中出現(xiàn)了,主要是用來(lái)申請(qǐng)中斷,比如下面
BOOL RetVal = KernelIoControl( IOCTL_HAL_REQUEST_SYSINTR, &Irq, sizeof( Irq ),
pSysIntr, sizeof( *pSysIntr ), NULL );
-------------------其實(shí)他的作用遠(yuǎn)遠(yuǎn)不止申請(qǐng)/釋放中斷那么簡(jiǎn)單,下面來(lái)看看PB的幫助文檔。
http://shoufuban.net/
This function provides the kernel with a generic I/O control for carrying out I/O operations.
BOOL KernelIoControl(
DWORD dwIoControlCode,
LPVOID lpInBuf,
DWORD nInBufSize,
LPVOID lpOutBuf,
DWORD nOutBufSize,
LPDWORD lpBytesReturned
);對(duì)于這個(gè)函數(shù)的參數(shù),非常類(lèi)似EVC中的DeviceIoControl,從說(shuō)明可以了解參數(shù)的使用方法。
Parameters
dwIoControlCode
[in] I/O control code, which should support the OAL I/O controls. For a list of these I/O controls, see OAL IOCTLs.
lpInBuf
[out] Pointer to a buffer that contains the data required to perform the operation.
Set to NULL if the dwIoControlCode parameter specifies an operation that does not require input data.
nInBufSize
[in] Size, in bytes, of the buffer pointed to by lpInBuf.
lpOutBuf
[out] Pointer to a buffer that receives the output data for the operation.
Set to NULL if the dwIoControlCode parameter specifies an operation that does not produce output data.
nOutBufSize
[in] Size, in bytes, of the buffer pointed to by lpOutBuf.
lpBytesReturned
[in] Long pointer to a variable that receives the size, in bytes, of the data stored in the buffer pointed to by lpOutBuf. Even when an operation produces no output data, and lpOutBuf is NULL, the KernelIoControl function uses the variable pointed to by lpBytesReturned. After such an operation, the value of the variable has no meaning.
Return Values
TRUE indicates success; FALSE indicates failure.
Remarks
The kernel calls the OEMIoControl function when a device driver or application calls the kernel function KernelIoControl and passes an I/O control code.
(當(dāng)應(yīng)用程序或者驅(qū)動(dòng)調(diào)用KernelIoControl 的時(shí)候,KernelIoControl 就會(huì)調(diào)用OEMIoControl 去實(shí)現(xiàn)。)
This function is also called when the SystemParametersInfo function is called with SPI_GETOEMINFO or SPI_GETPLATFORMINFO.
The system is fully preemptible when this function is called. The kernel does no processing, but it passes all parameters directly to the function supplied by you. (當(dāng)這個(gè)函數(shù)被調(diào)用的時(shí)候系統(tǒng)完全可能被搶占,內(nèi)核沒(méi)有處理,直接傳遞參數(shù)到你提供的函數(shù)。這個(gè)我覺(jué)得說(shuō)的很別扭,估計(jì)是直接傳遞參數(shù)到OEMIoControl )
This function is provided solely to allow your device driver or application to communicate with an OAL and its specific functionality.
(該函數(shù)用來(lái)提供驅(qū)動(dòng)/應(yīng)用程序和OAL的通信)
Requirements
OS Versions: Windows CE 2.10 and later.
Header: Pkfuncs.h.(原來(lái)是個(gè)不開(kāi)源的函數(shù))
Link Library: Coredll.lib.
========================現(xiàn)在來(lái)看看OEMIoControl 這個(gè)函數(shù)============================
C:\WINCE500\PLATFORM\COMMON\SRC\COMMON\IOCTL\ioctl.c(45):// Function: OEMIoControl
// File: ioctl.c
//
// File implements OEMIoControl function.
//
#include <windows.h>
#include <oal.h> //這個(gè)很關(guān)鍵,不然oal_ioctl_tab.h設(shè)置就沒(méi)有辦法傳遞進(jìn)來(lái)。
//------------------------------------------------------------------------------
//
// Global: g_ioctlState;
//
// This state variable contains critical section used to serialize IOCTL
// calls.
//
static struct {
BOOL postInit;
CRITICAL_SECTION cs;
} g_ioctlState = { FALSE };
//------------------------------------------------------------------------------
//
// Include: intioctl.c
//
// This include file is used to add internal testing IOCTL hadlers.
//
#ifdef OAL_HAL_INTERNAL_TESTING
#include "intioctl.c"
#endif
//------------------------------------------------------------------------------
//
// 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
));
// 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) {
#ifdef OAL_HAL_INTERNAL_TESTING
rc = InternalHalTesting(
code, pInBuffer, inSize, pOutBuffer, outSize, pOutSize
);
#else
NKSetLastError(ERROR_NOT_SUPPORTED);
OALMSG(OAL_WARN, (
L"OEMIoControl: Unsupported Code 0x%x - device 0x%04x func %d\r\n",
code, code >> 16, (code >> 2)
));
#endif
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 調(diào)用函數(shù)指針,用來(lái)實(shí)現(xiàn)相應(yīng)功能
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
) {
// Take critical section
LeaveCriticalSection(&g_ioctlState.cs);
} else if (!g_ioctlState.postInit && code == IOCTL_HAL_POSTINIT) {
// Initialize critical section
InitializeCriticalSection(&g_ioctlState.cs);
g_ioctlState.postInit = TRUE;
}
cleanUp:
OALMSG(OAL_IOCTL&&OAL_FUNC, (L"-OEMIoControl(rc = %d)\r\n", rc ));
return rc;
}
//------------------------------------------------------------------------------
——再來(lái)看oal_ioctl.h
//------------------------------------------------------------------------------
//
// File: oal_ioctl.h
//
// This header file defines IO Control OAL module. This module implements
// OEMIoControl function which is used to call kernel functions from user
// space.
//
#ifndef __OAL_IOCTL_H
#define __OAL_IOCTL_H
#if __cplusplus
extern "C" {
#endif
//------------------------------------------------------------------------------
//
// Definition: OAL_IOCTL_FLAG_xxx
//
// This definition specifies flag codes for IOCTL table. When NOCS flag is
// set handler function will be called in deserialized mode (so no critical
// section will be taken/release before/after handler is called).
//
#define OAL_IOCTL_FLAG_NOCS (1 << 0)
//------------------------------------------------------------------------------
//
// Type: IOCTL_HANDLER
//
// This type defines the procedure to be called for an IOCTL code. The
// global g_oalIoctlTable is an array of these types.
//
typedef struct {
UINT32 code;
UINT32 flags;
BOOL (*pfnHandler)(UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);
} OAL_IOCTL_HANDLER, *POAL_IOCTL_HANDLER;
//------------------------------------------------------------------------------
//
// Extern: g_oalIoCtlPlatformType/OEM
//
// Platform Type/OEM
//
extern LPCWSTR g_oalIoCtlPlatformType;
extern LPCWSTR g_oalIoCtlPlatformOEM;
//------------------------------------------------------------------------------
//
// Global: g_oalIoCtlProcessorVendor/Name/Core
//
// Processor information
//
extern LPCWSTR g_oalIoCtlProcessorVendor;
extern LPCWSTR g_oalIoCtlProcessorName;
extern LPCWSTR g_oalIoCtlProcessorCore;
//------------------------------------------------------------------------------
//
// Global: g_oalIoCtlInstructionSet/g_oalIoCtlClockSpeed
//
// Processor instruction set identifier and clock speed
//
extern UINT32 g_oalIoCtlInstructionSet;
extern UINT32 g_oalIoCtlClockSpeed;
//------------------------------------------------------------------------------
//
// Globaal: g_oalIoctlTable
//
// This extern references the global IOCTL table that is defined in
// the platform code.
//
extern const OAL_IOCTL_HANDLER g_oalIoCtlTable[];
//------------------------------------------------------------------------------
//
// Function: OALIoCtlXxx
//
// This functions implement basic IOCTL code handlers.
// 這些函數(shù)在哪里實(shí)現(xiàn)的呢?功能好強(qiáng)大
BOOL OALIoCtlHalGetDeviceId(UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);
BOOL OALIoCtlHalGetDeviceInfo(UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);
BOOL OALIoCtlProcessorInfo(UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);
BOOL OALIoCtlHalInitRegistry(UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);
BOOL OALIoCtlHalReboot(UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);
BOOL OALIoCtlHalGetUUID (UINT32, VOID *, UINT32, VOID *, UINT32, UINT32 *);
//------------------------------------------------------------------------------
//
// Function: OALIoCtlHalDDIXxx
//
// This functions implement IOCTL code handler used by HAL flat display
// driver.
//
BOOL OALIoCtlHalDDI(UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);
//------------------------------------------------------------------------------
#if __cplusplus
}
#endif
#endif // __OAL_IOCTL_H
再看oal_ioctl_tab.h
//------------------------------------------------------------------------------
// 這個(gè)頭文件很關(guān)鍵,只要在這里填入相應(yīng)的IOCTL_XXXXX以及相應(yīng)的函數(shù)
// (在別的地方實(shí)現(xiàn)這個(gè)函數(shù))就大功告成了。
// File: oal_ioctl_tab.h
//
// This file contains part of global IOCTL handler table for codes which
// must (or should) be implemented on all platforms. Table in platform
// will usually include this file.
//
// This file is included by the platform's IOCTL table, g_oalIoCtlTable[].
// Therefore, this file may ONLY define OAL_IOCTL_HANDLER entries.
//
// IOCTL CODE, Flags Handler Function
//------------------------------------------------------------------------------
{ IOCTL_HAL_TRANSLATE_IRQ, 0, OALIoCtlHalRequestSysIntr },
{ IOCTL_HAL_REQUEST_SYSINTR, 0, OALIoCtlHalRequestSysIntr },
{ IOCTL_HAL_RELEASE_SYSINTR, 0, OALIoCtlHalReleaseSysIntr },
{ IOCTL_HAL_REQUEST_IRQ, 0, OALIoCtlHalRequestIrq },
{ IOCTL_HAL_INITREGISTRY, 0, OALIoCtlHalInitRegistry },
{ IOCTL_HAL_INIT_RTC, 0, OALIoCtlHalInitRTC },
{ IOCTL_HAL_REBOOT, 0, OALIoCtlHalReboot },
{ IOCTL_HAL_DDK_CALL, 0, OALIoCtlHalDdkCall },
{ IOCTL_HAL_DISABLE_WAKE, 0, OALIoCtlHalDisableWake },
{ IOCTL_HAL_ENABLE_WAKE, 0, OALIoCtlHalEnableWake },
{ IOCTL_HAL_GET_WAKE_SOURCE, 0, OALIoCtlHalGetWakeSource },
{ IOCTL_HAL_GET_CACHE_INFO, 0, OALIoCtlHalGetCacheInfo },
{ IOCTL_HAL_GET_DEVICEID, 0, OALIoCtlHalGetDeviceId },
{ IOCTL_HAL_GET_DEVICE_INFO, 0, OALIoCtlHalGetDeviceInfo },
{ IOCTL_HAL_GET_UUID, 0, OALIoCtlHalGetUUID },
{ IOCTL_PROCESSOR_INFORMATION, 0, OALIoCtlProcessorInfo },
{ IOCTL_VBRIDGE_802_3_MULTICAST_LIST, 0, OALIoCtlVBridge },
{ IOCTL_VBRIDGE_ADD_MAC, 0, OALIoCtlVBridge },
{ IOCTL_VBRIDGE_CURRENT_PACKET_FILTER, 0, OALIoCtlVBridge },
{ IOCTL_VBRIDGE_GET_ETHERNET_MAC, 0, OALIoCtlVBridge },
{ IOCTL_VBRIDGE_GET_RX_PACKET, 0, OALIoCtlVBridge },
{ IOCTL_VBRIDGE_GET_RX_PACKET_COMPLETE, 0, OALIoCtlVBridge },
{ IOCTL_VBRIDGE_GET_TX_PACKET, 0, OALIoCtlVBridge },
{ IOCTL_VBRIDGE_GET_TX_PACKET_COMPLETE, 0, OALIoCtlVBridge },
{ IOCTL_VBRIDGE_SHARED_ETHERNET, 0, OALIoCtlVBridge },
{ IOCTL_VBRIDGE_WILD_CARD, 0, OALIoCtlVBridge },
{ IOCTL_VBRIDGE_WILD_CARD_RESET_BUFFER, 0, OALIoCtlVBridge },
{ IOCTL_VBRIDGE_WILD_CARD_VB_INITIALIZED, 0, OALIoCtlVBridge },
在初始化階段內(nèi)核就會(huì)調(diào)用KernelIoControl來(lái)和OAL通信,其實(shí)就是通過(guò)調(diào)用KernelIoControl來(lái)執(zhí)行OEMIoControl
很神奇吧。申請(qǐng)中斷什么的,都在這里弄好了。牛B!
==============================例子:重啟
如何在程序中關(guān)閉、重起和硬起動(dòng)Pocket PC?
--------------------------------------------------------------------------------
時(shí)間:2003-2-28 18:18:44 來(lái)源:BIPLIP.com 作者:Daric 閱讀210次
關(guān)閉(suspend)
方法1:
//虛擬關(guān)機(jī)鍵
::keybd_event(VK_OFF, 0, 0, 0);
::keybd_event(VK_OFF, 0, KEYEVENTF_KEYUP, 0);
方法2:
//調(diào)用未公開(kāi)函數(shù)PowerOffSystem()
extern "C" __declspec(dllimport) void PowerOffSystem();
重起(soft reset)
//Soft reset the device
#include
#define IOCTL_HAL_REBOOT CTL_CODE(FILE_DEVICE_HAL, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
extern "C" __declspec(dllimport) BOOL KernelIoControl(
DWORD dwIoControlCode,
LPVOID lpInBuf,
DWORD nInBufSize,
LPVOID lpOutBuf,
DWORD nOutBufSize,
LPDWORD lpBytesReturned);
BOOL ResetPocketPC()
{
return KernelIoControl(IOCTL_HAL_REBOOT, NULL, 0, NULL, 0, NULL);
}
硬起動(dòng)(hard reset)
//注意?。?!使用此段代碼會(huì)將您的Pocket PC的用戶(hù)數(shù)據(jù)全部清空,
//請(qǐng)勿非法使用,用者后果自負(fù).
#include
#define IOCTL_HAL_REBOOT CTL_CODE(FILE_DEVICE_HAL, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
extern "C" __declspec(dllimport)void SetCleanRebootFlag(void);
extern "C" __declspec(dllimport) BOOL KernelIoControl(
DWORD dwIoControlCode,
LPVOID lpInBuf,
DWORD nInBufSize,
LPVOID lpOutBuf,
DWORD nOutBufSize,
LPDWORD lpBytesReturned);
BOOL HardResetPocketPC()
{
SetCleanRebootFlag();
return KernelIoControl(IOCTL_HAL_REBOOT, NULL, 0, NULL, 0, NULL);
}
本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://shoufuban.net/
WinCE OAL中的OEMIoControl函數(shù)
http://shoufuban.net/
關(guān)于OEMIoControl函數(shù),我在2008年1月份寫(xiě)過(guò)一篇blog叫“WinCE BSP中OAL層中的OEMIoControl介紹”,已經(jīng)比較詳細(xì)的介紹了OEMIoControl,今天在這里只是對(duì)OEMIoControl中比較常用的case說(shuō)一說(shuō)。看看PB的文檔就知道OEMIoControl可以包含很多case而且被分了類(lèi)。下面就我個(gè)人接觸到的和比較常用的做個(gè)說(shuō)明:
1. IOCTL_HAL_INIT_RTC:
對(duì)應(yīng)OALIoctlHalInitRTC函數(shù),該case用于重新初始化RTC。在系統(tǒng)冷啟動(dòng)的時(shí)候,內(nèi)核會(huì)調(diào)用它來(lái)設(shè)置時(shí)鐘。
dwIoControlCode:IOCTL_HAL_INIT_RTC
lpInBuf:要設(shè)置的時(shí)鐘結(jié)構(gòu)體
實(shí)際上在該case中一般都是注冊(cè)RTC的ALARM中斷,然后調(diào)用OEMSetRealTime函數(shù)來(lái)進(jìn)行設(shè)置。關(guān)于OAL中的RTC的說(shuō)明,可以參考我在2008年1月寫(xiě)的“WinCE中RTC驅(qū)動(dòng)開(kāi)發(fā)介紹”。
2. IOCTL_HAL_POSTINIT:
對(duì)應(yīng)OALIoctlHalPostInit函數(shù),該case會(huì)被內(nèi)核調(diào)用,不傳入任何數(shù)據(jù),也不返回任何數(shù)據(jù)。在系統(tǒng)進(jìn)程啟動(dòng)之前,它提供了最后一次機(jī)會(huì)讓我們?cè)?/SPAN>OAL中做一些動(dòng)作。
3. IOCTL_HAL_ILTIMING:
對(duì)應(yīng)OALIoctlHalILTiming函數(shù),該case實(shí)現(xiàn)了對(duì)ILTiming的支持,當(dāng)Iltiming.exe運(yùn)行時(shí),該case會(huì)被調(diào)用。
dwIoControlCode:IOCTL_HAL_ILTIMING
lpInBuf:傳入ILTiming結(jié)構(gòu)
4. IOCTL_HAL_REBOOT:
對(duì)應(yīng)OALIoctlHalReboot函數(shù),該case用于熱啟動(dòng)系統(tǒng)。
5. IOCTL_HAL_ENABLE_WAKE:
對(duì)應(yīng)OALIoctlHalEnableWake函數(shù),該case用于添加可喚醒系統(tǒng)的中斷源。
dwIoControlCode:IOCTL_HAL_ENABLE_WAKE
lpInBuf:可喚醒系統(tǒng)的系統(tǒng)中斷號(hào)
6. IOCTL_HAL_DISABLE_WAKE:
對(duì)應(yīng)OALIoctlHalDisableWake函數(shù),該case用于刪除可喚醒系統(tǒng)的中斷源。
dwIoControlCode:IOCTL_HAL_DISABLE_WAKE
lpInBuf:被刪除的系統(tǒng)中斷號(hào)
7. IOCTL_HAL_GET_HIVE_CLEAN_FLAG:
對(duì)應(yīng)OALIoctlHalGetHiveCleanFlag函數(shù),該case會(huì)被Filesys模塊調(diào)用,用于確定是否清除系統(tǒng)Hive和用戶(hù)Hive。
dwIoControlCode:IOCTL_HAL_GET_HIVE_CLEAN_FLAG
lpInBuf:HIVECLEANFLAG_SYSTEM表示查詢(xún)系統(tǒng)Hive;HIVECLEANFLAG_USERS表示查詢(xún)用戶(hù)Hive
lpOutBuf:返回TRUE表示清除,返回FALSE表示不清除
8. IOCTL_HAL_GET_HIVE_RAM_REGION:
對(duì)應(yīng)OALIoctlHalGetHiveRamRegion函數(shù),該case會(huì)被Filesys模塊調(diào)用,返回一塊內(nèi)存區(qū)域用來(lái)存放Hive,此時(shí)系統(tǒng)Hive和用戶(hù)Hive是存放在一起的,所以所有的用戶(hù)都使用同一個(gè)用戶(hù)Hive。
dwIoControlCode:IOCTL_HAL_GET_HIVE_RAM_REGION
lpOutBuf:返回一個(gè)存放Hive的RAM結(jié)構(gòu)信息
9. IOCTL_HAL_QUERY_FORMAT_PARTITION:
對(duì)應(yīng)OALIoctlHalQueryFormatPartition函數(shù),該case會(huì)被Filesys模塊調(diào)用,返回是否需要格式化某個(gè)分區(qū)。對(duì)于一塊存儲(chǔ)介質(zhì)來(lái)說(shuō),如果在該介質(zhì)驅(qū)動(dòng)的注冊(cè)表配置中設(shè)置了CheckForFormat項(xiàng),Filesys模塊才會(huì)調(diào)用該case,例如:
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MyProfile\FATFS]
"CheckForFormat"=dword:1
dwIoControlCode:IOCTL_HAL_QUERY_FORMAT_PARTITION
lpInBuf:傳入存儲(chǔ)介質(zhì)的信息
lpOutBuf:返回TRUE表示該分區(qū)需要格式化,返回FALSE表示不需要格式化
..........
在WinCE的BSP中的OAL部分,會(huì)有一個(gè)ioctl.c或者oemioctl.c文件,里面主要定義了一個(gè)叫OEMIoControl(..)的函數(shù)。可以說(shuō)OEMIoControl是一個(gè)很有用的WinCE內(nèi)核輸入/輸出函數(shù)。
在WinCE5.0中,應(yīng)用程序和驅(qū)動(dòng)程序可以通過(guò)調(diào)用KernelIoControl(..)函數(shù)來(lái)訪問(wèn)WinCE內(nèi)核,導(dǎo)致調(diào)用OEMIoControl函數(shù),這樣應(yīng)用程序和驅(qū)動(dòng)程序就可以訪問(wèn)到OAL中的資源了。但在WinCE6.0中,提供了更好的安全性,應(yīng)用程序能夠訪問(wèn)OEMIoControl中的case受到了限制,只有下面的這些case是可以讓?xiě)?yīng)用程序訪問(wèn)的:
IOCTL_HAL_GET_CACHE_INFO
IOCTL_HAL_GET_DEVICE_INFO
IOCTL_HAL_GET_DEVICEID
IOCTL_HAL_GET_UUID
IOCTL_PROCESSOR_INFORMATION
如果用戶(hù)在應(yīng)用程序中試圖訪問(wèn)其他的case,肯定會(huì)返回失敗的。在WinCE6.0中,驅(qū)動(dòng)程序還像以前一樣,可以訪問(wèn)OEMIoControl中的任何case。也許有人會(huì)問(wèn),那么我們?nèi)绾巫寫(xiě)?yīng)用程序也訪問(wèn)到一些case呢??
辦法還是有的,可以看一下\WINCE600\public\common\oak\oalioctl\oalioctl.c,這個(gè)文件中定義了應(yīng)用程序可以訪問(wèn)的case,把你的應(yīng)用程序要訪問(wèn)的case加到這個(gè)文件中的IOControl(..)函數(shù)中就可以了。當(dāng)然,你需要重新編譯\public目錄。
在WinCE5.0中,OEMIoControl函數(shù)被定義在BSP中的OAL部分,上面已經(jīng)提到,應(yīng)該是ioctl.c或者oemioctl.c,但是在WinCE6.0中,這個(gè)函數(shù)的定義被移到了\WINCE600\platform\common\src\common\ioctl\ioctl.c中了,這里面的OEMIoControl函數(shù)和以前也有了變化,該函數(shù)會(huì)查一個(gè)表:g_oalIoCtlTable[]。該表實(shí)際上是一個(gè)結(jié)構(gòu)數(shù)組,定義了OEMIoControl中所有的case,已經(jīng)針對(duì)這個(gè)case的處理函數(shù),還包括一個(gè)針對(duì)每個(gè)case的flag,該flag表示是否使用臨界區(qū)保護(hù)。具體定義如下:
typedef struct { UINT32 code; UINT32 flags; BOOL (*pfnHandler) (UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);} OAL_IOCTL_HANDLER, *POAL_IOCTL_HANDLER;
所以,在WinCE6.0的BSP中,我們只需要實(shí)現(xiàn)g_oalIoCtlTable[]就可以了。例如:
const OAL_IOCTL_HANDLER g_oalIoCtlTable[]={
{ IOCTL_HAL_POSTINIT, 0, OALIoCtlHalPostInit },
{ IOCTL_HAL_GET_HIVE_CLEAN_FLAG, 0, OALIoCtlHalGetHiveCleanFlag },
{ IOCTL_HAL_GET_HWENTROPY, 0, OALIoCtlHalGetHWEntropy },
{ IOCTL_HAL_GET_IMAGE_SIGNED_STATE, 0, OALIoCtlHalGetImageSignedState },
{ IOCTL_HAL_QUERY_FORMAT_PARTITION, 0, OALIoCtlHalQueryFormatPartition },
{ 0, 0, NULL}
};
在OEMIoControl函數(shù)中,我們不光要實(shí)現(xiàn)OEMIoControl中的case,有一些全局的OAL變量我們也需要定義:
g_oalIoCtlClockSpeed |
This global variable contains information about the processor clock speed. |
g_oalIoCtlInstructionSet |
This global variable contains the processor instruction set identifier. |
g_oalIoCtlPlatformOEM |
This global variable contains information about the hardware platform OEM. |
g_oalIoCtlPlatformType |
This global variable contains information about the hardware platform type. |
g_oalIoCtlProcessorCore |
This global variable contains information about the processor core. |
g_oalIoCtlProcessorName |
This global variable contains information about the processor name. |
g_oalIoCtlProcessorVendor |
This global variable contains information about the processor vendor. |
其實(shí)都是一些硬件及平臺(tái)的相關(guān)信息,定義一下就可以了。
有時(shí)根據(jù)具體需要,我們還希望在OEMIoControl函數(shù)中添加自己定義的case,這個(gè)比較簡(jiǎn)單,只要定義個(gè)case,然后在這個(gè)case下寫(xiě)你的實(shí)現(xiàn)代碼就可以了,驅(qū)動(dòng)程序通過(guò)KernelIoControl調(diào)用同樣的case就可以調(diào)用到你在OEMIoControl中定義的case了。關(guān)于case值得定義,一般都在2048到4096之間會(huì)比較安全,我記得在WinCE6.0下,看微軟的代碼好像256以上就可以了,具體沒(méi)有試過(guò),要是保險(xiǎn)的話,還是用2048以上的值吧。