【WM】谈Phone Canvas函数为何不会返回错误值RPC_E_WRONG_THREAD
2009-08-30 11:31
405 查看
微软向OEM厂商提供Phone Canvas机制,让我们可以修改cprog.exe的数个界面布局和UI交互行为。
我们发现多数Phone Canvas API函数的返回值列表中都存在错误值RPC_E_WRONG_THREAD,下表就是PHGetBlobPtr的返回值列表:
理论上,Phone Canvas API函数必须在主UI线程调用,否则调用Phone Canvas API函数会返回错误值RPC_E_WRONG_THREAD。但实际使用下来,我们发现无论怎么调用Phone Canvas API函数都不会返回RPC_E_WRONG_THREAD,出于好奇我反汇编了tpcutil.dll对其调用机制一探究竟。
以下是根据笔者反汇编所得,改用C/C++描述的InitializePHCanvas函数实现,该函数用于加载Phone Canvas模块:
g_hMainCProgThread最初被赋值了GetCurrentThread()函数的返回值。
下面是PHGetBlobPtr函数的实现:
笔者注意到与g_hMainCProgThread比较的是GetCurrentThread()函数返回值,我们已知g_hMainCProgThread也是GetCurrentThread()函数的返回值,而且GetCurrentThread()函数无论在哪个线程里调用都返回一个数值相同的伪句柄。
所以,这个分支是永远进入不了的,PHGetBlobPtr函数也永远不会返回错误值RPC_E_WRONG_THREAD了。
我们发现多数Phone Canvas API函数的返回值列表中都存在错误值RPC_E_WRONG_THREAD,下表就是PHGetBlobPtr的返回值列表:
S_OK | Indicates success. |
E_INVALIDARG | Indicates failure. |
E_PENDING | Indicates this phone data identifier has no associated data yet. For example, PH_ID_LASTCALL_INFO before any calls have been made. |
RPC_E_WRONG_THREAD | Indicates that this function must be called from the main UI thread, since all of the phone canvas APIs are called on the main UI thread. |
以下是根据笔者反汇编所得,改用C/C++描述的InitializePHCanvas函数实现,该函数用于加载Phone Canvas模块:
HRESULT InitializePHCanvas(HWND hwndOwner, ICProg *pCprog, IPOutlookApp2 *polApp) { DWORD dwEnabled = 0; HKEY hKey = NULL; HRESULT hr = S_OK; if (!pCprog) { hr = E_INVALIDARG; goto Error; } g_pCprog = pCprog; g_hMainCProgThread = GetCurrentThread(); VoIPFeatureLevel = 0; SHGetDeviceFeatureLevel(SHDFLI_VOIP); ... }
g_hMainCProgThread最初被赋值了GetCurrentThread()函数的返回值。
下面是PHGetBlobPtr函数的实现:
HRESULT PHGetBlobPtr(PH_ID phid, DWORD* pcb, const BYTE** ppb) { if (g_hMainCProgThread != GetCurrentThread()) { return RPC_E_WRONG_THREAD; } if (!g_pCProg) { return E_FAIL; } ... }
笔者注意到与g_hMainCProgThread比较的是GetCurrentThread()函数返回值,我们已知g_hMainCProgThread也是GetCurrentThread()函数的返回值,而且GetCurrentThread()函数无论在哪个线程里调用都返回一个数值相同的伪句柄。
所以,这个分支是永远进入不了的,PHGetBlobPtr函数也永远不会返回错误值RPC_E_WRONG_THREAD了。
相关文章推荐
- UNIX环境高级编程学习笔记(十)为何 fork 函数会有两个不同的返回值【转】
- 10g 自定义功能为WM_CONCAT的函数,返回CLOB
- 参数返回Oracle 常用函数:nvl/nullif/case when/wm_concat/replace
- C++ static成员直到整个程序结束才释放空间,函数返回也不会释放
- UNIX环境高级编程学习笔记(十)为何 fork 函数会有两个不同的返回值
- 【WM】Phone Canvas重复创建视图的原因
- 【WM】Phone Canvas提示信息对照表
- ajax请求为异步操作时,返回的数据不会被并列函数执行
- 写一个函数返回1+2+3+…+n的值(假定结果不会超过长整型变量的范围)
- WMSYS.WM_CONCAT函数返回结果为CLOB引起视图无法创建
- MFC 用afxbeginthread创建线程 线程函数直接 return 0 返回。任务管理器显示线程数与理论值不符
- Linux下客户端主动Close,服务端阻塞的read函数不会马上返回
- Think Python 学习笔记6:有返回函数 迭代
- Oracle行转列函数wm_concat
- windows核心编程--函数返回错误
- CreateThread()线程创建函数,AfxBeginThread等
- [LWIP学习]--tcpip_input,tcpip_inpkt,tcpip_thread函数分析(协议栈入口)
- C++函数返回局部变量指针的问题
- 编写一个函数的返回值value的二进制位模式从左到右翻转后的值
- C#调用C++DLL的小总结8---C++Dll中函数返回字符串指针