2011年8月24日 星期三

Windows CE 的 kernelIoControl


這些是 KernelIoControl 中 FILE_DEVICE_HAL 用的 control code, 號碼是十進位, 這些是從 FreeScale 的 BSP 裡挖出來的, 還不是全部的 Control Code..

CTL_CODE(FILE_DEVICE_HAL, xx, METHOD_BUFFERED, FILE_ANY_ACCESS)

xx:
01 HAL_GET_DEVICE_INFO
03 HAL_GET_IP_ADDR
04 HAL_RADIO_CNTRL
05 HAL_DDK_CALL
06 EDBG_REGISTER_CLIENT
07 EDBG_DEREGISTER_CLIENT
08 EDBG_REGISTER_DFLT_CLIENT
09 EDBG_SEND
10 EDBG_RECV
11 EDBG_SET_DEBUG
78 KITL_STARTUP
79 KITL_INTRINIT
80 KITL_IS_KDBG_REGISTERED

// KITL PowerOn/Off ioctl, *lpInBuf = 0 for off, 1 for on.
81 KITL_POWER_CALL
12 SET_KERNEL_COMM_DEV
13 HAL_GET_UUID
14 HAL_INIT_RTC
15 HAL_REBOOT
16 HAL_HALT
17 SET_KERNEL_DEV_PORT
18 HAL_TRANSLATE_IRQ
19 HAL_GET_RIO_INFO
20 HAL_ILTIMING
21 HAL_GET_DEVICEID
22 HAL_PROFILE
23 HAL_SET_DEVICE_INFO
24 QUERY_PHYSICALMEM
25 PROCESSOR_INFORMATION
35 HAL_GETREGSECUREKEYS
36 HAL_REQUEST_IRQ
38 HAL_REQUEST_SYSINTR
54 HAL_RELEASE_SYSINTR
// IOCTL to get KITL transport info
37 KITL_GET_INFO
40 HAL_ENABLE_WAKE
41 HAL_DISABLE_WAKE
42 HAL_GET_WAKE_SOURCE
61 HAL_PRESUSPEND
// IOCTL to tell OEM to initialize registry on boot
44 HAL_INITREGISTRY

// IOCTL to give OEM a more full-featured init when the kernel is ready to go
// and before any apps are started
45 HAL_POSTINIT

// IOCTL to ask OEM whether to force clean registry hive
49 HAL_GET_HIVE_CLEAN_FLAG

// IOCTL to ask OEM the reason for power on
50 HAL_GET_POWERONREASON

// IOCTL to get random hardware seed
52 HAL_GET_RANDOM_SEED

// IOCTL to ask OEM for a RAM region to put the registry hive into
53 GET_HIVE_RAM_REGION

// IOCTL to tell OEM to save the RAM region where the registry hive is stored
55 SAVE_HIVE_RAM_REGION

// IOCTL to write XIP section.
46 HAL_WRITE_XIP
47 HAL_XIPCHAIN

// IOCTL for authenticate device
60 HAL_AUTHENTICATE_DEVICE

// IOCTL for WHQL testing (used to check whether hardware is in a jumpered test mode)
56 WHQL_TEST_MODE

// IOCTL for retrieving location and size of bootloader in flash
57 HAL_GET_BOOTLOADER_PARAMS

// IOCTL for retrieving the signed state of an OS image
58 HAL_GET_IMAGE_SIGNED_STATE

// IOCTL to query for a default display resolution.
63 HAL_QUERY_DISPLAYSETTINGS

// IOCTL to query device for device-specific information
64 HAL_QUERY_DEVICE_SETTINGS

// IOCTL to allow the HAL to override the extension region
65 HAL_GET_BIN_CHAIN

// IOCTL to retrieve cache information
66 HAL_GET_CACHE_INFO

// IOCTL to control OEM-specified profiler
67 HAL_OEM_PROFILER

// IOCTL to allow the networking component interrupts to use one SYSINTR_NETWORK_SHARED
68 HAL_SYSINTR_NETWORK_SHARED

// IOCTL to allow OEM specify MAC address for RNDIS
69 HAL_GET_RNDIS_MACADDR

// IOCTL to allow OEM's to specify if a partition is to be formated before being mounted.
70 HAL_QUERY_FORMAT_PARTITION

// IOCTL used by halflat display driver
71 HAL_DDI

// This IOCTL enables/disables update mode. It's used when updating system images and it sets/clears a flag in
// an OEM-defined location that's interpreted by the initial program loader (IPL) at boot time. Based on the
// flag, the IPL will either boot the OS image or it'll load the update loader which starts the update process.
//
// The IOCTL takes a single boolean input parameter: TRUE == update mode and FALSE == normal OS
//
77 HAL_UPDATE_MODE

// IOCTL used by kernel to query page pool parameters from the OAL
// The IOCTL takes no input parameters but returns an NKPoolParameters struct as output.
82 HAL_GET_POOL_PARAMETERS

////////////////////////////////////////////////////////////////////////////////
// VBridge support in kernel, used by VMini (Null miniport driver).
//
26 VBRIDGE_GET_TX_PACKET
27 VBRIDGE_GET_TX_PACKET_COMPLETE
28 VBRIDGE_GET_RX_PACKET
29 VBRIDGE_GET_RX_PACKET_COMPLETE
30 VBRIDGE_GET_ETHERNET_MAC
31 VBRIDGE_ADD_MAC
32 VBRIDGE_SHARED_ETHERNET
33 VBRIDGE_CURRENT_PACKET_FILTER
34 VBRIDGE_802_3_MULTICAST_LIST
39 VBRIDGE_WILD_CARD

//
// These are only handled in vbridge.lib
//

42 VBRIDGE_WILD_CARD_RESET_BUFFER
43 VBRIDGE_WILD_CARD_VB_INITIALIZED
// Ioctl to retrieve OutputDebugString
48 EDBG_GET_OUTPUT_DEBUG_FN
51 EDBG_IS_STARTED
// IOCTL to retrieve hardware-generated entropy
62 HAL_GET_HWENTROPY

例如呼叫已經被串接好的 RTC_init 就像這樣:
SYSTEMTIME tTIME = { 0 };
KernelIoControl(CTL_CODE(FILE_DEVICE_HAL, 14, METHOD_BUFFERED, FILE_ANY_ACCESS), &tTIME, sizeof(SYSTEMTIME), NULL, 0, NULL);

至於串接到 OEM function 這個是在 WinCE 裡被定義好的, 能不能改我就不確定了..
{WINCE_ROOT}\\PLATFORM\\COMMON\\SRC\\INC\\oal_ioctl_tab.h :

{ IOCTL_HAL_INIT_RTC, 0, OALIoCtlHalInitRTC },

2011年8月12日 星期五

嗯, 真的, why so serious?

我現在不會想那麼好心跟客戶打招呼, 我只是想告訴客戶, 前面有水雷, 不要過去.

2011年8月5日 星期五

Windows CE 輸入法...

先寫在這做筆記, 我不確定完全正確...
在做 windows CE 的東西時, 只要碰上非英語語系界面時都會碰上這個問題:

ERROR: C:\WINCE600\public\common\oak\drivers\keybd\LAYMGR\.\LayMgr.cpp line 1600: MapVirtualKey: No input language installed
ERROR: C:\WINCE600\public\common\oak\drivers\keybd\LAYMGR\.\LayMgr.cpp line 1411: KeybdDriverVKeyToUnicode: No input language installed

google 半天的結果當然是無解.. (google 能找到答案的問題本來就不叫問題..), 如 debug console 所說, 這是欠輸入法, 但只講對 1/5, 實際上這除了欠輸入法以外, 還欠 keyboard layout. 而更奇怪的是, CE 上 keyboard layout 竟然是用輸入法所用的代號..

以下假設是日文環境, 輸入法用 IME 3.1, BSP會這樣設定:
[HKEY_CURRENT_USER\Keyboard Layout\Preload]
@="00000411"
[HKEY_CURRENT_USER\Keyboard Layout\Preload\1]
@="00000411"

這個在 \wince600\PUBLIC\COMMON\OAK\DRIVERS\KEYBD\LAYMGR.reg 裡, 而被 BSP 用的 platform.reg include 進來:

[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Layouts\00000411]
"Layout File"="kbdmouse.dll"
"Layout Text"="Japanese"
"PS2_AT"="kbdmouse.dll"

但實際上這樣做有幾個問題在於
1.實際上沒有一個輸入法叫 00000411, 這是國家代碼, 當然不會是輸入法代碼..
2.IME 3.1 的輸入法代號叫 e001, 所以在 laymgr.cpp 中尋找的是 e0010411....
3.這個 e0010411 會在以上的 Preload 裡尋找, 如果沒有的話, 表示預設就沒有它..
4.這個 e0010411 也會 在 Layouts 裡尋找, 如果沒有, 就沒有對應表..

這個問題源自於 laymgr.cpp GetDefaultInputMethodName()中的一行
_tcsicmp( szTempInputMethodName, szTempDefaultInputMethodName)
(line 2963 at wince 6.0 R3 patch 2011-06-30) 中的判斷, 傳進去的是輸入法代碼 + 國碼一起比較, 也就所以為什麼英語語系 (00000409) 都沒有問題, 因為英語語系沒有輸入法, 前面都是0, 所以不會有找不到的問題.
(實際上我會建議在 laymgr.cpp 中安插自己的 debug message 把輸入法的代號 dump 出來, 以利日後 registery 值的建立.)

也就是說, 如果是用日文語系+IME的話, laymgr 會去找一個叫 "日文語系+IME" 的鍵盤, 實際上當然是不會有這種東西, 但我們要在 registery 裡造個假的去騙過檢查...

所以我現在用的設定是這樣子, 平臺是 FreeScale i.MX35

i.MX35 用的 platform registery key 在:
C:\WINCE600\PLATFORM\iMX35-3DS-PDK1_7\FILES\platform.reg
修改幾個:
; #include "$(DRIVERS_DIR)\keybd\LayMgr.reg" ;<= mark 掉
因為全域變數不一定 100% work, 所以被 include 進去的東西
往往會被設定成預設的 0409 而非想要的其它語系.

在最後面加上:
[HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\KEYBD]
"DriverName"="kbdmouse.dll" ;這是預設 driver.
[HKEY_CURRENT_USER\Keyboard Layout\Preload]
@="e0010411" ;預設使用的輸入法
[HKEY_CURRENT_USER\Keyboard Layout\Preload\1]
@="00000409" ;有這三個可以備選
[HKEY_CURRENT_USER\Keyboard Layout\Preload\2]
@="e0010411"
[HKEY_CURRENT_USER\Keyboard Layout\Preload\3]
@="00000411" ;這個是被列給 keyboard layout 用的.
[HKEY_LOCAL_MACHINE\Security\Policies]
@="00000411" ;這個不確定幹麻的.
[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Layouts\00000409]
"Layout File"="kbdmouse.dll" ;其實這裡指的都是對應表.
"Layout Text"="US"
"PS2_AT"="kbdmouse.dll"
[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Layouts\e0010411]
"Layout File"="KbdNopJpn1.dll" ;JPN IBM layout 是 jpn1, NEC 是 jpn2.
"Layout Text"="Japanese"
"PS2_AT"="KbdNopJpn1.dll"
[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Layouts\00000411]
"Layout File"="KbdNopJpn1.dll" ;這裡也要再設定一個.
"Layout Text"="Japanese"

其中指定用 kbdnopjpn1.dll 的主要原因, 是因為它有 export PS2AT_00000411 跟 IL_00000411 兩個 function 出來, 這個是 CE 一拿到就會有已經建好的東西, 其它像法文鍵盤等, 就要參考網路上的文章 (也是被找到最多的文章..)

開機進 CE 裡後, 還要先把輸入法切回英數再切回 IME 才可以兩個都載入進來.

ps. OS component 中, international->locale_specific_support->Japanese->Keyboard 確定要選. 而 NOP-en., NOP keyboard/mouse japan2 這兩個其實一定要選, 才會有 kbdnopjpn1.dll 被包進 kernel image 中, 圖中是因為 BSP 還啥的影響不能全選:


不過仍有繞路走的解法. 在 sysgen 時, 會幾乎把所有不管你有用到沒用到的 .DLL 全部編譯, 先盡可能浪費你所有的時間後, 然後再看要不要加進來... 也就是說, 編好後, 用搜尋是可以搜尋的到這些 .DLL 檔案的. 把這些 .DLL 檔案抓出來後, 可以用內建檔案的玩法給它內建在 kernel image 裡.
也就是修改 platform.bib, 加上
KbdNopJpn1.dll $(_FLATRELEASEDIR)\KbdNopJpn1.dll NK U
這樣在執行時, 會擺在 \\windows\\ 下, 輸入法檔案是可以找的到的.

先這樣, 這還不是很好的解法...