KernelIoControl和OEMIoControl的分析和使用(作者:wogoyixikexie@gliet)
来源:互联网 发布:网络诈骗的款能追回吗 编辑:程序博客网 时间:2024/05/20 02:27
对于KernelIoControl这个函数我们并不陌生,在2440 5.0BSP当中,这个函数在很多驱动中出现了,主要是用来申请中断,比如下面
BOOL RetVal = KernelIoControl( IOCTL_HAL_REQUEST_SYSINTR,
&Irq,
sizeof( Irq ),
pSysIntr,
sizeof( *pSysIntr ),
NULL );
-------------------其实他的作用远远不止申请/释放中断那么简单,下面来看看PB的帮助文档。
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 );
对于这个函数的参数,非常类似EVC中的DeviceIoControl,从说明可以了解参数的使用方法。
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.
(当应用程序或者驱动调用KernelIoControl 的时候,KernelIoControl 就会调用OEMIoControl 去实现。)
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. (当这个函数被调用的时候系统完全可能被抢占,内核没有处理,直接传递参数到你提供的函数。这个我觉得说的很别扭,估计是直接传递参数到OEMIoControl )
This function is provided solely to allow your device driver or application to communicate with an OAL and its specific functionality.
(该函数用来提供驱动/应用程序和OAL的通信)
Requirements
OS Versions: Windows CE 2.10 and later.
Header: Pkfuncs.h.(原来是个不开源的函数)
Link Library: Coredll.lib.
1 ========================现在来看看OEMIoControl 这个函数============================
2
3 C:/WINCE500/PLATFORM/COMMON/SRC/COMMON/IOCTL/ioctl.c(45):// Function: OEMIoControl
4
5 // File: ioctl.c
6 //
7 // File implements OEMIoControl function.
8 //
9 #include <windows.h>
10 #include <oal.h> //这个很关键,不然oal_ioctl_tab.h设置就没有办法传递进来。
11
12 //------------------------------------------------------------------------------
13 //
14 // Global: g_ioctlState;
15 //
16 // This state variable contains critical section used to serialize IOCTL
17 // calls.
18 //
19 static struct {
20 BOOL postInit;
21 CRITICAL_SECTION cs;
22 } g_ioctlState = { FALSE };
23
24 //------------------------------------------------------------------------------
25 //
26 // Include: intioctl.c
27 //
28 // This include file is used to add internal testing IOCTL hadlers.
29 //
30 #ifdef OAL_HAL_INTERNAL_TESTING
31 #include "intioctl.c"
32 #endif
33
34
35 //------------------------------------------------------------------------------
36 //
37 // Function: OEMIoControl
38 //
39 // The function is called by kernel a device driver or application calls
40 // KernelIoControl. The system is fully preemtible when this function is
41 // called. The kernel does no processing of this API. It is provided to
42 // allow an OEM device driver to communicate with kernel mode code.
43 //
44 BOOL OEMIoControl(
45 DWORD code, VOID *pInBuffer, DWORD inSize, VOID *pOutBuffer, DWORD outSize,
46 DWORD *pOutSize
47 ) {
48 BOOL rc = FALSE;
49 UINT32 i;
50
51 OALMSG(OAL_IOCTL&&OAL_FUNC, (
52 L"+OEMIoControl(0x%x, 0x%x, %d, 0x%x, %d, 0x%x)/r/n",
53 code, pInBuffer, inSize, pOutBuffer, outSize, pOutSize
54 ));
55
56 // Search the IOCTL table for the requested code.
57 for (i = 0; g_oalIoCtlTable[i].pfnHandler != NULL; i++) {
58 if (g_oalIoCtlTable[i].code == code) break;
59 }
60
61 // Indicate unsupported code
62 if (g_oalIoCtlTable[i].pfnHandler == NULL) {
63 #ifdef OAL_HAL_INTERNAL_TESTING
64 rc = InternalHalTesting(
65 code, pInBuffer, inSize, pOutBuffer, outSize, pOutSize
66 );
67 #else
68 NKSetLastError(ERROR_NOT_SUPPORTED);
69 OALMSG(OAL_WARN, (
70 L"OEMIoControl: Unsupported Code 0x%x - device 0x%04x func %d/r/n",
71 code, code >> 16, (code >> 2)
72 ));
73 #endif
74 goto cleanUp;
75 }
76
77 // Take critical section if required (after postinit & no flag)
78 if (
79 g_ioctlState.postInit &&
80 (g_oalIoCtlTable[i].flags & OAL_IOCTL_FLAG_NOCS) == 0
81 ) {
82 // Take critical section
83 EnterCriticalSection(&g_ioctlState.cs);
84 }
85
86 // Execute the handler 调用函数指针,用来实现相应功能
87 rc = g_oalIoCtlTable[i].pfnHandler(
88 code, pInBuffer, inSize, pOutBuffer, outSize, pOutSize
89 );
90
91 // Release critical section if it was taken above
92 if (
93 g_ioctlState.postInit &&
94 (g_oalIoCtlTable[i].flags & OAL_IOCTL_FLAG_NOCS) == 0
95 ) {
96 // Take critical section
97 LeaveCriticalSection(&g_ioctlState.cs);
98 } else if (!g_ioctlState.postInit && code == IOCTL_HAL_POSTINIT) {
99 // Initialize critical section
100 InitializeCriticalSection(&g_ioctlState.cs);
101 g_ioctlState.postInit = TRUE;
102 }
103
104 cleanUp:
105 OALMSG(OAL_IOCTL&&OAL_FUNC, (L"-OEMIoControl(rc = %d)/r/n", rc ));
106 return rc;
107 }
108
109 //------------------------------------------------------------------------------
110
111 ——再来看oal_ioctl.h
112
113 //------------------------------------------------------------------------------
114 //
115 // File: oal_ioctl.h
116 //
117 // This header file defines IO Control OAL module. This module implements
118 // OEMIoControl function which is used to call kernel functions from user
119 // space.
120 //
121 #ifndef __OAL_IOCTL_H
122 #define __OAL_IOCTL_H
123
124 #if __cplusplus
125 extern "C" {
126 #endif
127
128 //------------------------------------------------------------------------------
129 //
130 // Definition: OAL_IOCTL_FLAG_xxx
131 //
132 // This definition specifies flag codes for IOCTL table. When NOCS flag is
133 // set handler function will be called in deserialized mode (so no critical
134 // section will be taken/release before/after handler is called).
135 //
136 #define OAL_IOCTL_FLAG_NOCS (1 << 0)
137
138 //------------------------------------------------------------------------------
139 //
140 // Type: IOCTL_HANDLER
141 //
142 // This type defines the procedure to be called for an IOCTL code. The
143 // global g_oalIoctlTable is an array of these types.
144 //
145 typedef struct {
146 UINT32 code;
147 UINT32 flags;
148 BOOL (*pfnHandler)(UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);
149 } OAL_IOCTL_HANDLER, *POAL_IOCTL_HANDLER;
150
151 //------------------------------------------------------------------------------
152 //
153 // Extern: g_oalIoCtlPlatformType/OEM
154 //
155 // Platform Type/OEM
156 //
157 extern LPCWSTR g_oalIoCtlPlatformType;
158 extern LPCWSTR g_oalIoCtlPlatformOEM;
159
160 //------------------------------------------------------------------------------
161 //
162 // Global: g_oalIoCtlProcessorVendor/Name/Core
163 //
164 // Processor information
165 //
166 extern LPCWSTR g_oalIoCtlProcessorVendor;
167 extern LPCWSTR g_oalIoCtlProcessorName;
168 extern LPCWSTR g_oalIoCtlProcessorCore;
169
170 //------------------------------------------------------------------------------
171 //
172 // Global: g_oalIoCtlInstructionSet/g_oalIoCtlClockSpeed
173 //
174 // Processor instruction set identifier and clock speed
175 //
176
177 extern UINT32 g_oalIoCtlInstructionSet;
178 extern UINT32 g_oalIoCtlClockSpeed;
179
180 //------------------------------------------------------------------------------
181 //
182 // Globaal: g_oalIoctlTable
183 //
184 // This extern references the global IOCTL table that is defined in
185 // the platform code.
186 //
187 extern const OAL_IOCTL_HANDLER g_oalIoCtlTable[];
188
189 //------------------------------------------------------------------------------
190 //
191 // Function: OALIoCtlXxx
192 //
193 // This functions implement basic IOCTL code handlers.
194 // 这些函数在哪里实现的呢?功能好强大
195 BOOL OALIoCtlHalGetDeviceId(UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);
196 BOOL OALIoCtlHalGetDeviceInfo(UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);
197 BOOL OALIoCtlProcessorInfo(UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);
198 BOOL OALIoCtlHalInitRegistry(UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);
199 BOOL OALIoCtlHalReboot(UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);
200 BOOL OALIoCtlHalGetUUID (UINT32, VOID *, UINT32, VOID *, UINT32, UINT32 *);
201
202 //------------------------------------------------------------------------------
203 //
204 // Function: OALIoCtlHalDDIXxx
205 //
206 // This functions implement IOCTL code handler used by HAL flat display
207 // driver.
208 //
209 BOOL OALIoCtlHalDDI(UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);
210
211 //------------------------------------------------------------------------------
212
213
214 #if __cplusplus
215 }
216 #endif
217
218 #endif // __OAL_IOCTL_H
219 再看oal_ioctl_tab.h
220
221 //------------------------------------------------------------------------------
222 // 这个头文件很关键,只要在这里填入相应的IOCTL_XXXXX以及相应的函数
223 // (在别的地方实现这个函数)就大功告成了。
224 // File: oal_ioctl_tab.h
225 //
226 // This file contains part of global IOCTL handler table for codes which
227 // must (or should) be implemented on all platforms. Table in platform
228 // will usually include this file.
229 //
230 // This file is included by the platform's IOCTL table, g_oalIoCtlTable[].
231 // Therefore, this file may ONLY define OAL_IOCTL_HANDLER entries.
232 //
233 // IOCTL CODE, Flags Handler Function
234 //------------------------------------------------------------------------------
235
236 { IOCTL_HAL_TRANSLATE_IRQ, 0, OALIoCtlHalRequestSysIntr },
237 { IOCTL_HAL_REQUEST_SYSINTR, 0, OALIoCtlHalRequestSysIntr },
238 { IOCTL_HAL_RELEASE_SYSINTR, 0, OALIoCtlHalReleaseSysIntr },
239 { IOCTL_HAL_REQUEST_IRQ, 0, OALIoCtlHalRequestIrq },
240
241 { IOCTL_HAL_INITREGISTRY, 0, OALIoCtlHalInitRegistry },
242 { IOCTL_HAL_INIT_RTC, 0, OALIoCtlHalInitRTC },
243 { IOCTL_HAL_REBOOT, 0, OALIoCtlHalReboot },
244
245 { IOCTL_HAL_DDK_CALL, 0, OALIoCtlHalDdkCall },
246
247 { IOCTL_HAL_DISABLE_WAKE, 0, OALIoCtlHalDisableWake },
248 { IOCTL_HAL_ENABLE_WAKE, 0, OALIoCtlHalEnableWake },
249 { IOCTL_HAL_GET_WAKE_SOURCE, 0, OALIoCtlHalGetWakeSource },
250
251 { IOCTL_HAL_GET_CACHE_INFO, 0, OALIoCtlHalGetCacheInfo },
252 { IOCTL_HAL_GET_DEVICEID, 0, OALIoCtlHalGetDeviceId },
253 { IOCTL_HAL_GET_DEVICE_INFO, 0, OALIoCtlHalGetDeviceInfo },
254 { IOCTL_HAL_GET_UUID, 0, OALIoCtlHalGetUUID },
255 { IOCTL_PROCESSOR_INFORMATION, 0, OALIoCtlProcessorInfo },
256
257 { IOCTL_VBRIDGE_802_3_MULTICAST_LIST, 0, OALIoCtlVBridge },
258 { IOCTL_VBRIDGE_ADD_MAC, 0, OALIoCtlVBridge },
259 { IOCTL_VBRIDGE_CURRENT_PACKET_FILTER, 0, OALIoCtlVBridge },
260 { IOCTL_VBRIDGE_GET_ETHERNET_MAC, 0, OALIoCtlVBridge },
261 { IOCTL_VBRIDGE_GET_RX_PACKET, 0, OALIoCtlVBridge },
262 { IOCTL_VBRIDGE_GET_RX_PACKET_COMPLETE, 0, OALIoCtlVBridge },
263 { IOCTL_VBRIDGE_GET_TX_PACKET, 0, OALIoCtlVBridge },
264 { IOCTL_VBRIDGE_GET_TX_PACKET_COMPLETE, 0, OALIoCtlVBridge },
265 { IOCTL_VBRIDGE_SHARED_ETHERNET, 0, OALIoCtlVBridge },
266 { IOCTL_VBRIDGE_WILD_CARD, 0, OALIoCtlVBridge },
267 { IOCTL_VBRIDGE_WILD_CARD_RESET_BUFFER, 0, OALIoCtlVBridge },
268 { IOCTL_VBRIDGE_WILD_CARD_VB_INITIALIZED, 0, OALIoCtlVBridge },
269
270 在初始化阶段内核就会调用KernelIoControl来和OAL通信,其实就是通过调用KernelIoControl来执行OEMIoControl
271
272 很神奇吧。申请中断什么的,都在这里弄好了。牛B
273
- KernelIoControl和OEMIoControl的分析和使用(作者:wogoyixikexie@gliet)
- KernelIoControl和OEMIoControl的分析和使用(作者:wogoyixikexie@gliet)
- MMU代码分析(作者:wogoyixikexie@gliet)
- wince串口之MDD分析(作者:wogoyixikexie@gliet)
- wince 2440串口驱动PDD分析(作者:wogoyixikexie@gliet)
- 《转》 MMU代码分析(作者:wogoyixikexie@gliet)
- 如何在wince下添加和删除驱动(作者:wogoyixikexie@gliet)
- 如何删除wince的驱动(作者:wogoyixikexie@gliet)
- OEMAddressTable 内存映射表是怎么被wince使用的(作者:wogoyixikexie@gliet)
- 0UL是什么意思?(作者:wogoyixikexie@gliet)
- eboot中断学习(作者:wogoyixikexie@gliet)
- 反汇编stepldr.exe——第一次使用IDA反汇编(作者:wogoyixikexie@gliet)
- 反汇编stepldr.exe——第一次使用IDA反汇编(作者:wogoyixikexie@gliet)
- 反汇编stepldr.exe——第一次使用IDA反汇编(作者:wogoyixikexie@gliet)
- ZLG7290(wince下)驱动之不停执行同一动作的解决办法(作者:wogoyixikexie@gliet)
- wince 5.0 .2440 5.0BSP的中断过程(作者:wogoyixikexie@gliet)
- wince串口打印函数是如何实现的?(作者wogoyixikexie@gliet)
- 转:wince 5.0 .2440 5.0BSP的中断过程(作者:wogoyixikexie@gliet)
- 【转载】搜索引擎如何对付“暗网”
- 验证数字的正则表达式集
- Oracle DECODE
- 2010年5月5日(新公司入职,第五周星期三)
- SQLServer : EXEC和sp_executesql的区别
- KernelIoControl和OEMIoControl的分析和使用(作者:wogoyixikexie@gliet)
- ORACLE存储过程
- 如何区分一个初始化参数是静态还是动态的
- C#串口通信:MSComm控件使用详解
- BindException
- ASP.NET 页面事件执行顺序 收藏
- why we use abstract_class in active_record ?
- 重启系统后,登陆oracle数据库提示ORA-01034: ORACLE not available 怎么办?
- Web后台任务定时执行工具的设计与实现