這個方法是非特權api。
#include "tapi.h"
#include "tsp.h"
#define EXIT_ON_NULL(_p) /
if (_p == NULL) /
{ /
hr = E_OUTOFMEMORY; /
goto FuncExit; /
} #define EXIT_ON_FALSE(_f) /
if (!(_f)) /
{ /
hr = E_FAIL; /
goto FuncExit; /
} #define MAX(i, j) ((i) > (j) ? (i) : (j)) #define TAPI_API_LOW_VERSION 0x00020000
#define TAPI_API_HIGH_VERSION 0x00020000 #define CAPS_BUFFER_SIZE 512 HRESULT SHReadLineAddressCaps(LPTSTR szNumber, UINT cchNumber, PDWORD pdwCallFwdModes, UINT nLineNumber)
{
HRESULT hr = E_FAIL;
LRESULT lResult = 0;
HLINEAPP hLineApp;
DWORD dwNumDevs;
DWORD dwAPIVersion = TAPI_API_HIGH_VERSION;
LINEINITIALIZEEXPARAMS liep; DWORD dwTAPILineDeviceID;
const DWORD dwAddressID = nLineNumber - 1; liep.dwTotalSize = sizeof(liep);
liep.dwOptions = LINEINITIALIZEEXOPTION_USEEVENT; if (SUCCEEDED(lineInitializeEx(&hLineApp, 0, 0, TEXT("ExTapi_Lib"), &dwNumDevs, &dwAPIVersion, &liep)))
{ BYTE* pCapBuf = NULL;
DWORD dwCapBufSize = CAPS_BUFFER_SIZE;
LINEEXTENSIONID LineExtensionID;
LINEDEVCAPS* pLineDevCaps = NULL;
LINEADDRESSCAPS* placAddressCaps = NULL; pCapBuf = new BYTE[dwCapBufSize];
EXIT_ON_NULL(pCapBuf); pLineDevCaps = (LINEDEVCAPS*)pCapBuf;
pLineDevCaps->dwTotalSize = dwCapBufSize; // Get TSP Line Device ID
dwTAPILineDeviceID = 0xffffffff;
for (DWORD dwCurrentDevID = 0 ; dwCurrentDevID < dwNumDevs ; dwCurrentDevID++)
{
if (0 == lineNegotiateAPIVersion(hLineApp, dwCurrentDevID, TAPI_API_LOW_VERSION, TAPI_API_HIGH_VERSION,
&dwAPIVersion, &LineExtensionID))
{
lResult = lineGetDevCaps(hLineApp, dwCurrentDevID, dwAPIVersion, 0, pLineDevCaps); if (dwCapBufSize < pLineDevCaps->dwNeededSize)
{
delete[] pCapBuf;
dwCapBufSize = pLineDevCaps->dwNeededSize;
pCapBuf = new BYTE[dwCapBufSize];
EXIT_ON_NULL(pCapBuf); pLineDevCaps = (LINEDEVCAPS*)pCapBuf;
pLineDevCaps->dwTotalSize = dwCapBufSize; lResult = lineGetDevCaps(hLineApp, dwCurrentDevID, dwAPIVersion, 0, pLineDevCaps);
} if ((0 == lResult) &&
(0 == _tcscmp((TCHAR*)((BYTE*)pLineDevCaps+pLineDevCaps->dwLineNameOffset), CELLTSP_LINENAME_STRING)))
{
dwTAPILineDeviceID = dwCurrentDevID;
break;
}
}
} placAddressCaps = (LINEADDRESSCAPS*)pCapBuf;
placAddressCaps->dwTotalSize = dwCapBufSize; lResult = lineGetAddressCaps(hLineApp, dwTAPILineDeviceID, dwAddressID, dwAPIVersion, 0, placAddressCaps); if (dwCapBufSize < placAddressCaps->dwNeededSize)
{
delete[] pCapBuf;
dwCapBufSize = placAddressCaps->dwNeededSize;
pCapBuf = new BYTE[dwCapBufSize];
EXIT_ON_NULL(pCapBuf); placAddressCaps = (LINEADDRESSCAPS*)pCapBuf;
placAddressCaps->dwTotalSize = dwCapBufSize; lResult = lineGetAddressCaps(hLineApp, dwTAPILineDeviceID, dwAddressID, dwAPIVersion, 0, placAddressCaps);
} if (0 == lResult)
{
if (szNumber)
{
szNumber[0] = _T('/0'); EXIT_ON_FALSE(0 != placAddressCaps->dwAddressSize); // A non-zero dwAddressSize means a phone number was found
ASSERT(0 != placAddressCaps->dwAddressOffset);
PWCHAR tsAddress = (WCHAR*)(((BYTE*)placAddressCaps)+placAddressCaps->dwAddressOffset); StringCchCopy(szNumber, cchNumber, tsAddress);
} // Record the allowed forwarding modes
if (pdwCallFwdModes)
{
*pdwCallFwdModes = placAddressCaps->dwForwardModes;
} hr = S_OK;
} delete[] pCapBuf;
} // End if () FuncExit:
lineShutdown(hLineApp); return hr;
}
// szNumber - Out Buffer for the phone number //cchNumber - size of sznumber in characters // nLineNumber - which phone line (1 or 2) to get the number for
HRESULT SHGetPhoneNumber(LPTSTR szNumber, UINT cchNumber, UINT nLineNumber)
{
return SHReadLineAddressCaps(szNumber, cchNumber, NULL, nLineNumber);
}
并不是所有的手機号都能獲得: 10月21号的文章:擷取Windows Mobile手機的手機号碼一文中擷取手機号碼的方法并不是總是可以用的,經過測試,中國移動全球通的SIM卡,手機号是可以擷取的,而 動感地帶和 神州行的手機号根本就擷取不到,這不是程式的問題,而是中國移動的問題。同樣的SIM卡,放到其他的手機上(測試過Nokia 6170)也不能檢視本機号碼。