您的位置:首页 > 其它

【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的返回值列表:

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.

理论上,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模块:

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了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: