當在用 Visual Studio 試著 profile FAAC 的效率時
出現了bluescreen : STOP 0x0000004A
IRQL_GT_ZERO_AT_SYSTEM_SERVICE
而這是我在 Mac Mini (2011) 上還未出現過的現象
經過了Google 一番 終於解決了這個問題
原因是 Visual Studio 2008 SP1 Team System Profiler 在Nehalem或者之後的CPU 用sampling profiler 會hang, 因為當時 Nehalem還沒上市, 而profiler 的 driver (VsPerfDrv90.sys) 是跟 CPU硬體息息相關的.
解決方法很簡單,只要下載 KB958842 Hotfix 並安裝後就ok
http://archive.msdn.microsoft.com/KB958842
2012年7月30日 星期一
compile FAAC in MIPS
在 Project libmp4v2_st mpeg4ip_win32.h 中
Error:
沒有 errno.h
沒有 io.h
沒有 fcntl.h
沒有 sys/types.h
沒有 sys/stat.h
沒有 sys/timeb.h
沒有 vsnprintf_s 改成 _vsnprintf
沒有 printf_s 及 fprintf_s 改成 printf 及 fprintf
沒有 ERANGE EACCES EINVAL --> 從 WIN32 errno.h copy
Project faac input.c
沒有 O_BINARY 用 _O_BINARY
沒有 perror()
沒有 rewind() 用fseek( sndf->f, 0, SEEK_SET); 取代
main.c
沒有 SetConsoleTitle()
mp4file.cpp
沒有 GetTempFileNameA() 要改成 GetTempFileNameW()
沒有 remove() 跟 rename()
getopt.c
沒有 getenv()
need_for_win32.c
沒有 sys/timeb.h so 沒有 _ftime() 所以要改寫 gettimeofday
mp4util.c
沒有 strerror()
Link 時會出現
會出現 沒有 WinMainCRTStartup 錯誤
fuck!
WIN32 的 entry point 是 wmainCRTStartup 或 mainCRTStartup
而 WINCE 的 entry point 是 mainWCRTStartup 或 mainACRTStartup
http://msdn.microsoft.com/en-us/library/f9t8842e(v=vs.80).aspx
沒有 _ntohl , link WS2.lib
Link Error:
(In faacgui)
unresolved external symbol:
DragAcceptFiles
沒有WM_DROPFILES
發現 faac, mp4creator(mp4muxer) 用的都是 libmp4v2
Error:
沒有 errno.h
沒有 io.h
沒有 fcntl.h
沒有 sys/types.h
沒有 sys/stat.h
沒有 sys/timeb.h
沒有 vsnprintf_s 改成 _vsnprintf
沒有 printf_s 及 fprintf_s 改成 printf 及 fprintf
沒有 ERANGE EACCES EINVAL --> 從 WIN32 errno.h copy
Project faac input.c
沒有 O_BINARY 用 _O_BINARY
沒有 perror()
沒有 rewind() 用fseek( sndf->f, 0, SEEK_SET); 取代
main.c
沒有 SetConsoleTitle()
mp4file.cpp
沒有 GetTempFileNameA() 要改成 GetTempFileNameW()
沒有 remove() 跟 rename()
getopt.c
沒有 getenv()
need_for_win32.c
沒有 sys/timeb.h so 沒有 _ftime() 所以要改寫 gettimeofday
mp4util.c
沒有 strerror()
Link 時會出現
fatal error LNK1112: module machine type 'mips' conflicts with target machine type 'x86'
在 project faac 的 Link 額外選項 把/Machine:i386 刪掉
會出現 沒有 WinMainCRTStartup 錯誤
fuck!
WIN32 的 entry point 是 wmainCRTStartup 或 mainCRTStartup
而 WINCE 的 entry point 是 mainWCRTStartup 或 mainACRTStartup
http://msdn.microsoft.com/en-us/library/f9t8842e(v=vs.80).aspx
沒有 _ntohl , link WS2.lib
Link Error:
(In faacgui)
unresolved external symbol:
DragAcceptFiles
沒有WM_DROPFILES
發現 faac, mp4creator(mp4muxer) 用的都是 libmp4v2
2012年7月23日 星期一
Port LAME MP3 Encoder to MIPS WINCE
DL LAME 3.99.5
基本上打開 vc9_lame.sln 就可以build 了,但是這是 Windows 版本
選擇 solution platform
改成 STANDARDSDK_500 (MIPS)
copy from WIN32
基本上
從Windows porting 到 WINCE 會遇到下列問題
1. WINCE 沒有
signal.h
errno.h
fcntl.h
io.h
沒有
sys/types.h
sys/stat.h
sys/timeb.h
沒有
SetPriorityClass(), ftime()
沒定義 _IOFBF, 其值為0
2. 要定義 _MIPS_, 跟 STRSAFE_NO_DEPRECATE
STDIN_FILENO, STDOUT_FILENO。STDERR_FILENO
http://checko.blogspot.tw/2006/03/file-and-stream-stdin-and-stdinfileno.html
http://www.mail-archive.com/dev@apr.apache.org/msg18982.html
http://forum.soft32.com/pda/Porting-app-GetStdHandle-ftopict51244.html
3. 最好定義 _WIN32_WCE, Link Subsystem 要指定為WINDOWSCE
在 build LAME 時 會出現一個 warning
'strdup' undefined; assuming extern returning int
把 strdup 改成 _strdup 就好了
4. mpglib & libmp3lame 容易過關
但是frontend 的 lame.exe 部份就要修改
lametime.c 沒有 clock(), time(),
parse.c 沒有 FindFirstFileA 要改成 FindFirstFileW
沒有 SetPriorityClass(), WINCE 是直接 map 248-255 這8個 (0 最高255最低)
Windows 是6個Priority Class 7個 Priority Level
6 * 7 = 42 種組合 map 到 0-31 priority ( 0 最低)
5. 沒有 stdint.h 這個檔案是c99 相關的, VS2008 (包含)以前的版本都不支援,(VS2008 C99 支援很差?) 在Visual Studio 2010 的版本,放在 \vc\include 下
6. 有 setvbuf 卻沒有定義 _IOFBF _IONBF ...
最後有一堆 Linking Error
因為用 wmain 所 entry point 要設成 mainWCRTStartup
lame_get_file_size 的問題
需要在 FILE* 和 HANDLE 之間轉換
_get_osfhandle 可以把 file descriptor 轉成 file handle
_fileno 可以把 file pointer (FILE*) 轉成 file descriptor
但是
在WINCE下沒有 _get_osfhandle
基本上打開 vc9_lame.sln 就可以build 了,但是這是 Windows 版本
選擇 solution platform
改成 STANDARDSDK_500 (MIPS)
copy from WIN32
基本上
從Windows porting 到 WINCE 會遇到下列問題
1. WINCE 沒有
signal.h
errno.h
fcntl.h
io.h
沒有
sys/types.h
sys/stat.h
sys/timeb.h
沒有
SetPriorityClass(), ftime()
沒定義 _IOFBF, 其值為0
2. 要定義 _MIPS_, 跟 STRSAFE_NO_DEPRECATE
STDIN_FILENO, STDOUT_FILENO。STDERR_FILENO
http://checko.blogspot.tw/2006/03/file-and-stream-stdin-and-stdinfileno.html
http://www.mail-archive.com/dev@apr.apache.org/msg18982.html
http://forum.soft32.com/pda/Porting-app-GetStdHandle-ftopict51244.html
3. 最好定義 _WIN32_WCE, Link Subsystem 要指定為WINDOWSCE
在 build LAME 時 會出現一個 warning
'strdup' undefined; assuming extern returning int
把 strdup 改成 _strdup 就好了
4. mpglib & libmp3lame 容易過關
但是frontend 的 lame.exe 部份就要修改
lametime.c 沒有 clock(), time(),
parse.c 沒有 FindFirstFileA 要改成 FindFirstFileW
沒有 SetPriorityClass(), WINCE 是直接 map 248-255 這8個 (0 最高255最低)
Windows 是6個Priority Class 7個 Priority Level
6 * 7 = 42 種組合 map 到 0-31 priority ( 0 最低)
5. 沒有 stdint.h 這個檔案是c99 相關的, VS2008 (包含)以前的版本都不支援,(VS2008 C99 支援很差?) 在Visual Studio 2010 的版本,放在 \vc\include 下
6. 有 setvbuf 卻沒有定義 _IOFBF _IONBF ...
最後有一堆 Linking Error
因為用 wmain 所 entry point 要設成 mainWCRTStartup
Windows CE supports the following CRT entry points:
- mainACRTStartup for applications that define the main function
- mainWCRTStartup for applications that define the wmain function
- WinMainCRTStartup for applications that define the WinMain function
- wWinMainCRTStartup for applications that define the wWinMain function
- _DllMainCRTStartup for DLLs
沒有 _wgetenv, GetConsoleOutputCP
沒有 powf, log10f 改成 pow, log10
沒有 time(), 因為被 preprocessor 改成 _time64()
lame_get_file_size 的問題
需要在 FILE* 和 HANDLE 之間轉換
_get_osfhandle 可以把 file descriptor 轉成 file handle
_fileno 可以把 file pointer (FILE*) 轉成 file descriptor
但是
在WINCE下沒有 _get_osfhandle
2012年4月25日 星期三
Apple Lossless Codec (ALAC)
Apple Lossless 已經open source 了, 是一個很好的選擇
試著build , Windows 的版本 很簡單 沒啥問題 只是如果用VS2010 以前的
要自己下載 stdint.h
stdint.h 是 C99 標準 可以在 http://code.google.com/p/msinttypes/ 下載
然後build MIPS 版本
會出現 error C2733: second C linkage of overloaded function 'wmemchr' not allowed
那是因為 stdint.h include wchar.h
而且加上 extern "C"
#ifdef __cplusplus
extern "C" {
#endif
# include
#ifdef __cplusplus
}
因為 C 不能 第二次 link 到 overloaded function
所以會出現C2733 錯誤
而且Apple Lossless Solution 把一些 .c 檔都當成 c++ (/TP) 來 compile
如果把那些 .c 檔用 c 的方式來compile 就不會出現 C2733
不過會出現奇怪錯誤 error C2054: expected '(' to follow 'inline'
那是因為 C 沒有 inline keyword 要用 __inline
2種改法都行
應該是 sdk 中的 wchar.h 有問題 跟 win32 的 wchar.h 不一樣
sdk 中的 wchar.h 好像有明顯錯誤
在win32 中 wchar.h
wmemchr, wcschr, wcspbrk, wcsrchr, wcsstr
都是用 extern "C++" 括起來
但是 standard sdk 中卻沒有(應該是錯誤)
如果修改,移出 extern "C" 然後把 wmemchr, wcschr, wcspbrk, wcsrchr, wcsstr
用 extern "C++" 括起來, 就可以過關
第三種改法
改 stdint.h , extern "C" 改成 extern "C++"
#ifdef __cplusplus
extern "C++" {
#endif
# include
#ifdef __cplusplus
}
然後繼續編譯, Link 出現一些問題
0. Link subsystem specify WindowsCE
1. unresolved external symbol __security_check_cookie 使用 /GS- 即可 ( Buffer Security Check OFF )
2. memset... function 沒有
要Link coredll.lib 或 corelibc.lib
在此不能用 coredll.lib 因為沒有 startup function like mainACRTStartup
也沒有 exit()
http://msdn.microsoft.com/en-us/library/ms859584.aspx
最後 編譯完的EXE 到 MIPS上跑
結果不能run 顯示 cannot find one of its component
不知道少了什麼
只好用 dependency walker
http://www.dependencywalker.com/
發現少了 msvcr90d.dll
解決方法之一 是把 compiler option /MDd 改成 /MTd
就ok了 ^^
http://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.80).aspx
http://blog.monkeypotion.net/gameprog/beginner/love-and-hate-between-msvc-and-crt
Exception
事情總是沒那麼簡單,alacConvert 實際上在MIPS run 時,出現了Exception
code 是 0x80000002 address 000124A8
怎麼看 exception code 呢
之前都沒仔細研究
後來查到有關的 2個 API GetExceptionCode 跟 RaiseException
追到 Exception Code 的定義在 winbase.h 然後又定義在 winnt.h(WIN32) 或 ntstatus.h (ARM)
#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION
#define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT
#define EXCEPTION_BREAKPOINT STATUS_BREAKPOINT
最常見的是
EXCEPTION_ACCESS_VIOLATION 0xC0000005
再來 alignment fault 可以用 __unaligned 來解決或者自己copy (byte by byte)
Address 的話, 產生 .map 檔跟 listing files來觀察即可
note: __unaligned 是Microsoft specific
在Linux 中, 用 get_unaligned() 和 put_unaligned() macro
http://lwn.net/Articles/260456/
試著build , Windows 的版本 很簡單 沒啥問題 只是如果用VS2010 以前的
要自己下載 stdint.h
stdint.h 是 C99 標準 可以在 http://code.google.com/p/msinttypes/ 下載
然後build MIPS 版本
會出現 error C2733: second C linkage of overloaded function 'wmemchr' not allowed
那是因為 stdint.h include wchar.h
而且加上 extern "C"
#ifdef __cplusplus
extern "C" {
#endif
# include
#ifdef __cplusplus
}
因為 C 不能 第二次 link 到 overloaded function
所以會出現C2733 錯誤
而且Apple Lossless Solution 把一些 .c 檔都當成 c++ (/TP) 來 compile
如果把那些 .c 檔用 c 的方式來compile 就不會出現 C2733
不過會出現奇怪錯誤 error C2054: expected '(' to follow 'inline'
那是因為 C 沒有 inline keyword 要用 __inline
2種改法都行
應該是 sdk 中的 wchar.h 有問題 跟 win32 的 wchar.h 不一樣
sdk 中的 wchar.h 好像有明顯錯誤
在win32 中 wchar.h
wmemchr, wcschr, wcspbrk, wcsrchr, wcsstr
都是用 extern "C++" 括起來
但是 standard sdk 中卻沒有(應該是錯誤)
如果修改,移出 extern "C" 然後把 wmemchr, wcschr, wcspbrk, wcsrchr, wcsstr
用 extern "C++" 括起來, 就可以過關
第三種改法
改 stdint.h , extern "C" 改成 extern "C++"
#ifdef __cplusplus
extern "C++" {
#endif
# include
#ifdef __cplusplus
}
然後繼續編譯, Link 出現一些問題
0. Link subsystem specify WindowsCE
1. unresolved external symbol __security_check_cookie 使用 /GS- 即可 ( Buffer Security Check OFF )
2. memset... function 沒有
要Link coredll.lib 或 corelibc.lib
在此不能用 coredll.lib 因為沒有 startup function like mainACRTStartup
也沒有 exit()
http://msdn.microsoft.com/en-us/library/ms859584.aspx
最後 編譯完的EXE 到 MIPS上跑
結果不能run 顯示 cannot find one of its component
不知道少了什麼
只好用 dependency walker
http://www.dependencywalker.com/
發現少了 msvcr90d.dll
解決方法之一 是把 compiler option /MDd 改成 /MTd
就ok了 ^^
http://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.80).aspx
http://blog.monkeypotion.net/gameprog/beginner/love-and-hate-between-msvc-and-crt
Exception
事情總是沒那麼簡單,alacConvert 實際上在MIPS run 時,出現了Exception
code 是 0x80000002 address 000124A8
怎麼看 exception code 呢
之前都沒仔細研究
後來查到有關的 2個 API GetExceptionCode 跟 RaiseException
追到 Exception Code 的定義在 winbase.h 然後又定義在 winnt.h(WIN32) 或 ntstatus.h (ARM)
#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION
#define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT
#define EXCEPTION_BREAKPOINT STATUS_BREAKPOINT
最常見的是
EXCEPTION_ACCESS_VIOLATION 0xC0000005
EXCEPTION_DATATYPE_MISALIGNMENT 0x80000002
這兩個
再來 alignment fault 可以用 __unaligned 來解決或者自己copy (byte by byte)
Address 的話, 產生 .map 檔跟 listing files來觀察即可
note: __unaligned 是Microsoft specific
在Linux 中, 用 get_unaligned() 和 put_unaligned() macro
The easiest way to avoid unaligned access is to use the get_unaligned() and put_unaligned() macros provided by theheader file.
http://lwn.net/Articles/260456/
2012年4月15日 星期日
Unknown IOCTL, IOCTL_PSL_NOTIFY
在使用 XXX_IOControl 的時候 發現會有不名的 IOCTL 自動進來
其code 為 0x10303FF (16974847)
經查結果如下
IOCTL_PSL_NOTIFY 是屬於 OAL IOCTL 之一
它在什麼時候被呼叫呢?
也就是當AP Process Main Thread 結束的時候
它呼叫Driver 的 thread 尚未結束(或被block住)
這時系統就會call IOCTL_PSL_NOTIFY 去通知Device Driver unblock, release 這個thread.
http://www.itlisting.org/4-windows-ce-embedded/81ac8dc06a35379f.aspx
hey...
This is IOCTL_PSL_NOTIFY (see common\oak\inc\pkfuncs.h). It's issued when a
process is exiting.
其code 為 0x10303FF (16974847)
經查結果如下
IOCTL_PSL_NOTIFY 是屬於 OAL IOCTL 之一
它在什麼時候被呼叫呢?
也就是當AP Process Main Thread 結束的時候
它呼叫Driver 的 thread 尚未結束(或被block住)
這時系統就會call IOCTL_PSL_NOTIFY 去通知Device Driver unblock, release 這個thread.
The OS uses this I/O control when all of the following conditions are true:
- The main application thread exits.
- The application has other threads still running.
- The application has open file handles that refer to the device.
http://www.itlisting.org/4-windows-ce-embedded/81ac8dc06a35379f.aspx
hey...
Why does my XXX_IOControl receive a unknown IOCTL code when closing my
application ??
application ??
The IOCTL code is received before the XXX_Close is called.
The received code is: 16974847 (0x10303FF)
What is causing this ???
What is this used for ???
What is this used for ???
This is IOCTL_PSL_NOTIFY (see common\oak\inc\pkfuncs.h). It's issued when a
process is exiting.
Basically what happens is this: when a process exits (i.e. the main thread
is terminating), all threads in that process will be terminated. Some of
these threads may be blocked inside drivers. This IOCTL is issued to all
drivers so that they can unblock these threads if they so desire (most
drivers ignore this, but check out the serial driver
(common\oak\drivers\serial\com_mdd2\mdd.c) for an example of how this might
be done.
is terminating), all threads in that process will be terminated. Some of
these threads may be blocked inside drivers. This IOCTL is issued to all
drivers so that they can unblock these threads if they so desire (most
drivers ignore this, but check out the serial driver
(common\oak\drivers\serial\com_mdd2\mdd.c) for an example of how this might
be done.
2012年4月12日 星期四
ActivateDevice
在WINCE 7 下,用RegisterDevice 會失敗 回傳1060 (ERROR_SERVICE_DOES_NOT_EXIST) 不知道為什麼。
只好改用 ActivateDevice
ActivateDevice 的第一個參數是 Registry Path 不包含HKEY_LOCAL_MACHINE
如 HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Netbios 就變成 "Drivers\BuiltIn\Netbios"
過程如下
當Registry 都沒設時 回傳 1060
當有設好一些 Registry 時 會回傳 1610 (ERROR_BAD_CONFIGURATION)
當都設好時 但是 .DLL 沒放到 \Windows 下 會回傳 2 (ERROR_FILE_NOT_FOUND)
當全部都好後 一直回傳 1 (ERROR_INVALID_FUNCTION)
最後才知道是 XXX_Init 沒有定義 export ( 用到舊的定義 一個參數)
只好改用 ActivateDevice
ActivateDevice 的第一個參數是 Registry Path 不包含HKEY_LOCAL_MACHINE
如 HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Netbios 就變成 "Drivers\BuiltIn\Netbios"
過程如下
當Registry 都沒設時 回傳 1060
當有設好一些 Registry 時 會回傳 1610 (ERROR_BAD_CONFIGURATION)
當都設好時 但是 .DLL 沒放到 \Windows 下 會回傳 2 (ERROR_FILE_NOT_FOUND)
當全部都好後 一直回傳 1 (ERROR_INVALID_FUNCTION)
最後才知道是 XXX_Init 沒有定義 export ( 用到舊的定義 一個參數)
VirtualCopy MmMapIoSpace in WINCE 6
http://discovertheexperience.blogspot.com/2009/04/windows-embedded-ce-60-memory-mapping.html
In Windows Embedded CE 6.0 there are some APIs which can only be called from Kernel Mode due to trust issues. The memory mapping APIs like VirtualCopy, MmMapIoSpace (which is a wrapper for VirtualAlloc and VirtualCopy), … now belong to those Kernel Mode only APIs. Consequently you might ask: “So there is no way to call MmMapIoSpace directly from User Mode?” Well not quite, there is but one exception and that is a User Mode driver. The reflector service of a particular User Mode driver which runs in Kernel Mode can call MmMapIoSpace on behalf of that User Mode driver. However, it will not do so unless it knows that the User Mode driver is allowed to access the addresses in question. But how does the reflector service get this information you might ask? Well It gets it from the User Mode driver’s registry: more specific from the IoBase and IoLen keys. You can also use multi-strings here to specify multiple base addresses and lengths. And since this part of the registry is only accessible by privileged applications we have a protection against unauthorized altering of those keys.
But what if you need to call a memory mapping API such asMmMapIoSpace from a User Mode application? How now brown cow? Well you got several options how to deal with this problem:
There is another important restriction on VirtualCopy and therefore also on MmMapIoSpace in Windows Embedded CE 6.0: Calls to either of these two memory mapping functions will fail if it crosses a 32 MB section boundary. To avoid this you may have to call these APIs multiple times.
http://blog.csdn.net/Jack__h/article/details/4939911
http://www.cppblog.com/milkyway/archive/2007/03/27/20738.html
VirtualCopy 的WINCE 5, 6, 7 的解釋各有不同,值得一看
WINCE 5 -- 傳統的, MEM_PHYSICAL 解釋不同, return 的address 2MB 不同
http://msdn.microsoft.com/en-us/library/aa450977.aspx
WINCE 6 -- 講了如何call API 的替代方法
http://msdn.microsoft.com/en-us/library/ee483154(v=winembedded.60).aspx
WINCE 7
http://msdn.microsoft.com/en-us/library/ee483154.aspx
In Windows Embedded CE 6.0 there are some APIs which can only be called from Kernel Mode due to trust issues. The memory mapping APIs like VirtualCopy, MmMapIoSpace (which is a wrapper for VirtualAlloc and VirtualCopy), … now belong to those Kernel Mode only APIs. Consequently you might ask: “So there is no way to call MmMapIoSpace directly from User Mode?” Well not quite, there is but one exception and that is a User Mode driver. The reflector service of a particular User Mode driver which runs in Kernel Mode can call MmMapIoSpace on behalf of that User Mode driver. However, it will not do so unless it knows that the User Mode driver is allowed to access the addresses in question. But how does the reflector service get this information you might ask? Well It gets it from the User Mode driver’s registry: more specific from the IoBase and IoLen keys. You can also use multi-strings here to specify multiple base addresses and lengths. And since this part of the registry is only accessible by privileged applications we have a protection against unauthorized altering of those keys.
But what if you need to call a memory mapping API such asMmMapIoSpace from a User Mode application? How now brown cow? Well you got several options how to deal with this problem:
- You can make the code that calls the memory mapping functions a driver. Remember to specify the IoBase and IoLenregistry keys if you make it a User Mode driver.
- You can make the code that calls the memory mapping functions into a DLL that you then have to load into the Kernel via LoadKernelLibrary.
- You can create a dummy Kernel Mode driver that implementsIOCTL_DO_VIRTUAL_COPY to call VirtualCopy.
There is another important restriction on VirtualCopy and therefore also on MmMapIoSpace in Windows Embedded CE 6.0: Calls to either of these two memory mapping functions will fail if it crosses a 32 MB section boundary. To avoid this you may have to call these APIs multiple times.
http://blog.csdn.net/Jack__h/article/details/4939911
http://www.cppblog.com/milkyway/archive/2007/03/27/20738.html
VirtualCopy 的WINCE 5, 6, 7 的解釋各有不同,值得一看
WINCE 5 -- 傳統的, MEM_PHYSICAL 解釋不同, return 的address 2MB 不同
http://msdn.microsoft.com/en-us/library/aa450977.aspx
WINCE 6 -- 講了如何call API 的替代方法
http://msdn.microsoft.com/en-us/library/ee483154(v=winembedded.60).aspx
WINCE 7
http://msdn.microsoft.com/en-us/library/ee483154.aspx
訂閱:
文章 (Atom)