KernelIoControl和OEMIoControl的分析和使用(作者:wogoyixikexie@gliet)

作者:wogoyixikexie@gliet 2008-12-18

 

    对于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.

 

========================现在来看看OEMIoControl 这个函数============================

C:/WINCE500/PLATFORM/COMMON/SRC/COMMON/IOCTL/ioctl.c(45)://  Function:  OEMIoControl

  1. //  File:  ioctl.c
  2. //
  3. //  File implements OEMIoControl function.
  4. //
  5. #include <windows.h>
  6. #include <oal.h>   //这个很关键,不然oal_ioctl_tab.h设置就没有办法传递进来。
  7. //------------------------------------------------------------------------------
  8. //
  9. //  Global:  g_ioctlState;
  10. //
  11. //  This state variable contains critical section used to serialize IOCTL
  12. //  calls.
  13. //
  14. static struct {
  15.     BOOL postInit;
  16.     CRITICAL_SECTION cs;
  17. } g_ioctlState = { FALSE };
  18. //------------------------------------------------------------------------------
  19. //
  20. //  Include: intioctl.c
  21. //
  22. //  This include file is used to add internal testing IOCTL hadlers.
  23. //
  24. #ifdef OAL_HAL_INTERNAL_TESTING
  25. #include "intioctl.c"
  26. #endif
  27. //------------------------------------------------------------------------------
  28. //
  29. //  Function:  OEMIoControl
  30. //
  31. //  The function is called by kernel a device driver or application calls 
  32. //  KernelIoControl. The system is fully preemtible when this function is 
  33. //  called. The kernel does no processing of this API. It is provided to 
  34. //  allow an OEM device driver to communicate with kernel mode code.
  35. //
  36. BOOL OEMIoControl(
  37.     DWORD code, VOID *pInBuffer, DWORD inSize, VOID *pOutBuffer, DWORD outSize,
  38.     DWORD *pOutSize
  39. ) {
  40.     BOOL rc = FALSE;
  41.     UINT32 i;
  42.     OALMSG(OAL_IOCTL&&OAL_FUNC, (
  43.         L"+OEMIoControl(0x%x, 0x%x, %d, 0x%x, %d, 0x%x)/r/n"
  44.         code, pInBuffer, inSize, pOutBuffer, outSize, pOutSize
  45.     ));
  46.     // Search the IOCTL table for the requested code.
  47.     for (i = 0; g_oalIoCtlTable[i].pfnHandler != NULL; i++) {
  48.         if (g_oalIoCtlTable[i].code == code) break;
  49.     }
  50.     // Indicate unsupported code
  51.     if (g_oalIoCtlTable[i].pfnHandler == NULL) {
  52. #ifdef OAL_HAL_INTERNAL_TESTING
  53.         rc = InternalHalTesting(
  54.             code, pInBuffer, inSize, pOutBuffer, outSize, pOutSize
  55.         );
  56. #else
  57.         NKSetLastError(ERROR_NOT_SUPPORTED);
  58.         OALMSG(OAL_WARN, (
  59.             L"OEMIoControl: Unsupported Code 0x%x - device 0x%04x func %d/r/n"
  60.             code, code >> 16, (code >> 2)
  61.         ));
  62. #endif
  63.         goto cleanUp;
  64.     }        
  65.     // Take critical section if required (after postinit & no flag)
  66.     if (
  67.         g_ioctlState.postInit && 
  68.         (g_oalIoCtlTable[i].flags & OAL_IOCTL_FLAG_NOCS) == 0
  69.     ) {
  70.         // Take critical section            
  71.         EnterCriticalSection(&g_ioctlState.cs);
  72.     }
  73.     // Execute the handler 调用函数指针,用来实现相应功能
  74.     rc = g_oalIoCtlTable[i].pfnHandler(
  75.         code, pInBuffer, inSize, pOutBuffer, outSize, pOutSize
  76.     );
  77.     // Release critical section if it was taken above
  78.     if (
  79.         g_ioctlState.postInit && 
  80.         (g_oalIoCtlTable[i].flags & OAL_IOCTL_FLAG_NOCS) == 0
  81.     ) {
  82.         // Take critical section            
  83.         LeaveCriticalSection(&g_ioctlState.cs);
  84.     } else if (!g_ioctlState.postInit && code == IOCTL_HAL_POSTINIT) {
  85.         // Initialize critical section
  86.         InitializeCriticalSection(&g_ioctlState.cs);
  87.         g_ioctlState.postInit = TRUE;
  88.     }                
  89. cleanUp:
  90.     OALMSG(OAL_IOCTL&&OAL_FUNC, (L"-OEMIoControl(rc = %d)/r/n", rc ));
  91.     return rc;
  92. }
  93. //------------------------------------------------------------------------------

——再来看oal_ioctl.h

  1. //------------------------------------------------------------------------------
  2. //
  3. //  File:  oal_ioctl.h
  4. //
  5. //  This header file defines IO Control OAL module. This module implements
  6. //  OEMIoControl function which is used to call kernel functions from user
  7. //  space.
  8. //
  9. #ifndef __OAL_IOCTL_H
  10. #define __OAL_IOCTL_H
  11. #if __cplusplus
  12. extern "C" {
  13. #endif
  14. //------------------------------------------------------------------------------
  15. //
  16. //  Definition: OAL_IOCTL_FLAG_xxx
  17. //
  18. //  This definition specifies flag codes for IOCTL table. When NOCS flag is
  19. //  set handler function will be called in deserialized mode (so no critical
  20. //  section will be taken/release before/after handler is called).
  21. //
  22. #define OAL_IOCTL_FLAG_NOCS     (1 << 0)
  23. //------------------------------------------------------------------------------
  24. //
  25. //  Type: IOCTL_HANDLER    
  26. //
  27. //  This type defines the procedure to be called for an IOCTL code. The
  28. //  global g_oalIoctlTable is an array of these types.
  29. //
  30. typedef struct {
  31.     UINT32  code;
  32.     UINT32  flags;
  33.     BOOL    (*pfnHandler)(UINT32VOID*, UINT32VOID*, UINT32UINT32*);
  34. } OAL_IOCTL_HANDLER, *POAL_IOCTL_HANDLER;
  35. //------------------------------------------------------------------------------
  36. //
  37. //  Extern: g_oalIoCtlPlatformType/OEM
  38. //
  39. //  Platform Type/OEM
  40. //
  41. extern LPCWSTR g_oalIoCtlPlatformType;
  42. extern LPCWSTR g_oalIoCtlPlatformOEM;
  43. //------------------------------------------------------------------------------
  44. //
  45. //  Global: g_oalIoCtlProcessorVendor/Name/Core
  46. //
  47. //  Processor information
  48. //
  49. extern LPCWSTR g_oalIoCtlProcessorVendor;
  50. extern LPCWSTR g_oalIoCtlProcessorName;
  51. extern LPCWSTR g_oalIoCtlProcessorCore;
  52. //------------------------------------------------------------------------------
  53. //
  54. //  Global:  g_oalIoCtlInstructionSet/g_oalIoCtlClockSpeed
  55. //
  56. //  Processor instruction set identifier and clock speed
  57. //
  58. extern UINT32 g_oalIoCtlInstructionSet;
  59. extern UINT32 g_oalIoCtlClockSpeed;
  60. //------------------------------------------------------------------------------
  61. //
  62. //  Globaal:  g_oalIoctlTable
  63. //
  64. //  This extern references the global IOCTL table that is defined in
  65. //  the platform code.
  66. //
  67. extern const OAL_IOCTL_HANDLER g_oalIoCtlTable[];
  68. //------------------------------------------------------------------------------
  69. //
  70. //  Function: OALIoCtlXxx
  71. //
  72. //  This functions implement basic IOCTL code handlers.
  73. //  这些函数在哪里实现的呢?功能好强大
  74. BOOL OALIoCtlHalGetDeviceId(UINT32VOID*, UINT32VOID*, UINT32UINT32*);
  75. BOOL OALIoCtlHalGetDeviceInfo(UINT32VOID*, UINT32VOID*, UINT32UINT32*);
  76. BOOL OALIoCtlProcessorInfo(UINT32VOID*, UINT32VOID*, UINT32UINT32*);
  77. BOOL OALIoCtlHalInitRegistry(UINT32VOID*, UINT32VOID*, UINT32UINT32*);
  78. BOOL OALIoCtlHalReboot(UINT32VOID*, UINT32VOID*, UINT32UINT32*);
  79. BOOL OALIoCtlHalGetUUID (UINT32VOID *, UINT32VOID *, UINT32UINT32 *);
  80. //------------------------------------------------------------------------------
  81. //
  82. //  Function: OALIoCtlHalDDIXxx
  83. //
  84. //  This functions implement IOCTL code handler used by HAL flat display
  85. //  driver.
  86. //
  87. BOOL OALIoCtlHalDDI(UINT32VOID*, UINT32VOID*, UINT32UINT32*);
  88. //------------------------------------------------------------------------------
  89. #if __cplusplus
  90. }
  91. #endif
  92. #endif // __OAL_IOCTL_H

    再看oal_ioctl_tab.h

  1. //------------------------------------------------------------------------------
  2. //  这个头文件很关键,只要在这里填入相应的IOCTL_XXXXX以及相应的函数
  3. // (在别的地方实现这个函数)就大功告成了。
  4. //  File:  oal_ioctl_tab.h
  5. //
  6. //  This file contains part of global IOCTL handler table for codes which
  7. //  must (or should) be implemented on all platforms. Table in platform
  8. //  will usually include this file.
  9. //
  10. //  This file is included by the platform's IOCTL table, g_oalIoCtlTable[].
  11. //  Therefore, this file may ONLY define OAL_IOCTL_HANDLER entries. 
  12. //
  13. // IOCTL CODE,                          Flags   Handler Function
  14. //------------------------------------------------------------------------------
  15. { IOCTL_HAL_TRANSLATE_IRQ,                  0,  OALIoCtlHalRequestSysIntr   },
  16. { IOCTL_HAL_REQUEST_SYSINTR,                0,  OALIoCtlHalRequestSysIntr   },
  17. { IOCTL_HAL_RELEASE_SYSINTR,                0,  OALIoCtlHalReleaseSysIntr   },
  18. { IOCTL_HAL_REQUEST_IRQ,                    0,  OALIoCtlHalRequestIrq       },
  19. { IOCTL_HAL_INITREGISTRY,                   0,  OALIoCtlHalInitRegistry     },
  20. { IOCTL_HAL_INIT_RTC,                       0,  OALIoCtlHalInitRTC          },
  21. { IOCTL_HAL_REBOOT,                         0,  OALIoCtlHalReboot           },
  22. { IOCTL_HAL_DDK_CALL,                       0,  OALIoCtlHalDdkCall          },
  23. { IOCTL_HAL_DISABLE_WAKE,                   0,  OALIoCtlHalDisableWake      },
  24. { IOCTL_HAL_ENABLE_WAKE,                    0,  OALIoCtlHalEnableWake       },
  25. { IOCTL_HAL_GET_WAKE_SOURCE,                0,  OALIoCtlHalGetWakeSource    },
  26. { IOCTL_HAL_GET_CACHE_INFO,                 0,  OALIoCtlHalGetCacheInfo     },
  27. { IOCTL_HAL_GET_DEVICEID,                   0,  OALIoCtlHalGetDeviceId      },
  28. { IOCTL_HAL_GET_DEVICE_INFO,                0,  OALIoCtlHalGetDeviceInfo    },
  29. { IOCTL_HAL_GET_UUID,                       0,  OALIoCtlHalGetUUID          },
  30. { IOCTL_PROCESSOR_INFORMATION,              0,  OALIoCtlProcessorInfo       },
  31. { IOCTL_VBRIDGE_802_3_MULTICAST_LIST,       0,  OALIoCtlVBridge             },
  32. { IOCTL_VBRIDGE_ADD_MAC,                    0,  OALIoCtlVBridge             },
  33. { IOCTL_VBRIDGE_CURRENT_PACKET_FILTER,      0,  OALIoCtlVBridge             },
  34. { IOCTL_VBRIDGE_GET_ETHERNET_MAC,           0,  OALIoCtlVBridge             },
  35. { IOCTL_VBRIDGE_GET_RX_PACKET,              0,  OALIoCtlVBridge             },
  36. { IOCTL_VBRIDGE_GET_RX_PACKET_COMPLETE,     0,  OALIoCtlVBridge             },
  37. { IOCTL_VBRIDGE_GET_TX_PACKET,              0,  OALIoCtlVBridge             },
  38. { IOCTL_VBRIDGE_GET_TX_PACKET_COMPLETE,     0,  OALIoCtlVBridge             },
  39. { IOCTL_VBRIDGE_SHARED_ETHERNET,            0,  OALIoCtlVBridge             },
  40. { IOCTL_VBRIDGE_WILD_CARD,                  0,  OALIoCtlVBridge             },
  41. { IOCTL_VBRIDGE_WILD_CARD_RESET_BUFFER,     0,  OALIoCtlVBridge             },
  42. { IOCTL_VBRIDGE_WILD_CARD_VB_INITIALIZED,   0,  OALIoCtlVBridge             },

在初始化阶段内核就会调用KernelIoControl来和OAL通信,其实就是通过调用KernelIoControl来执行OEMIoControl

很神奇吧。申请中断什么的,都在这里弄好了。牛B!

==============================例子:重启

如何在程序中关闭、重起和硬起动Pocket PC?

--------------------------------------------------------------------------------

时间:2003-2-28 18:18:44 来源:BIPLIP.com 作者:Daric 阅读210次


关闭(suspend)
方法1:
//虚拟关机键
::keybd_event(VK_OFF, 0, 0, 0);
::keybd_event(VK_OFF, 0, KEYEVENTF_KEYUP, 0);
方法2:
//调用未公开函数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);
}
硬起动(hard reset)
//注意!!!使用此段代码会将您的Pocket PC的用户数据全部清空,
//请勿非法使用,用者后果自负.
#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);
}

 

转载请标明:作者wogoyixikexie@gliet.桂林电子科技大学一系科协。如有错误,希望能够留言指出。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值