Jaa


Programmatically getting the phone number of a device

One question that is often asked is "How do I get the phone number of my device?" Usually the person asking doesn't really need the phone number, they just need some number that uniquely identifies the device. While there does exist an IOCTL to get a unique ID (not the phone number), only apps that are privileged are allowed to call it. (On a closed Smartphone, that means only apps that have been signed with a certificate that is in the device's privileged certificate store.) As an alternative, the code below shows how to get the phone number (without needing to be privileged).

 

 

#include "stdafx.h"
#include "windows.h"
#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);
}

Comments

  • Anonymous
    November 28, 2004
    How about some bluetooth things using the WinSock stack new BT APIs? Is Bluetooth being wrapped in 2.0 Base Class Libraries in .NET for this? If not, do you know a good .NET wrapper for Winsock bluetooth APIs?

  • Anonymous
    November 30, 2004
    Does this only work with the SIM cards that have the owners phone number stored?

  • Anonymous
    November 30, 2004
    Great. Now can you tell how to get current info from the embedded GPS device?

  • Anonymous
    December 01, 2004
    It seems like it takes a lot of code in this article to get the phone number. What is the difference with just making a single call to SmsGetPhoneNumber()?

    If you don't post a reply, is there any chance you could email it to me? jeff@activemap.com - thanks!

  • Anonymous
    December 09, 2004
    hi, im not sure why it doesn't work so i debug it myself and everything is success but ends to EXIT_ON_FALSE(0 != placAddressCaps->dwAddressSize);

    what causes this?
    thanks (progy at walla.com)

  • Anonymous
    December 19, 2004
    Hello.

    I am new to this stuff, and I just spent all Monday trying to get the code above to compile and link successfully. I am mostly using VB, both 6.0 and .NET, but I also have basic C/C++ knowledge.

    I have on my PC eVC++ 4.0 sp2, and the SDKs for Windows Mobile 2003 based Smartphones and PPC's.

    After many many moving around the .h files, I managed to compile this code, but I get 6 link errors like the one below:

    error LNK2019: unresolved external symbol _lineShutdown referenced in function "long __cdecl SHReadLineAddressCaps(unsigned short *,unsigned int,unsigned long *,unsigned int)" (?SHReadLineAddressCaps@@YAJPAGIPAKI@Z)

    Any help would be GREATLY appreciated.
    Kyriakos

  • Anonymous
    December 19, 2004
    Adding to the message above,

    please do contact me personally via email if you can help me with this program.

    k.lakkas@protonet.gr

    Kyriakos

  • Anonymous
    December 26, 2004
    I don't know why this code runs not stable. Some is good, but some is wrong.

    I got "" always on a Motorola MPX220, and I tried it not 2 lines, but 5 lines. nLineNumber = 1->5.

    Please help me!

  • Anonymous
    August 11, 2005
    I can't get the phone number. I also always got "" on a Motorola MPX220, and I also tried SmsGetPhoneNumber(), it also gave me "" for phone number. Could you tell me why and how to get the phone number correctly.
    BTW, I can get the deviceID using lineOpen(), lineGetGeneralInfo(), but have problem in getting the phone number. It could be great if you can help me for that.
    Please contact me at: aaron_zhang888@yahoo.ca
    Thanks.

    Aaron

  • Anonymous
    December 05, 2005
    The comment has been removed

  • Anonymous
    June 11, 2006
    Hi Jason
    IT will be very helpful for me if you can post the full source as a zip file so that I can convert it into a DLL and call it from my managed code can you please do it for me
    thanks
    Sri

  • Anonymous
    February 07, 2007
    This is my site: http://32url.com/?88KM ,This is my site: http://32url.com/?88KM

  • Anonymous
    February 28, 2007
    hi jason, we r developing an telephony application on windows mobile 5.0 using  .net cf 2.0.we r able to control the speaker phone volume but not able to control the headset volume. IT will be very helpful for us if u can help us in this.

  • Anonymous
    April 03, 2007
    HI GUYZ! This code works fine on windows mobile smartphone 5.0 emulator.But not working on device.Same case is also happening with SmsGetPhoneNumber(). can anybody suggest any way out.

  • Anonymous
    May 03, 2007
    Hello. I have problem with enter to this site via GPRS. Please, help me. Thanks! Best regards.

  • Anonymous
    May 07, 2007
    Hi, I try to use the code but the result is always empty could please explain me the reason of this result

  • Anonymous
    October 08, 2007
    I tried it. But the result is also always empty. Can someone please help?

  • Anonymous
    October 08, 2007
    My email is shellyshao@hotmail.com. I tried above sample and the sample from msdn, always get empty phone number. Help is greatly appreciated.

  • Anonymous
    January 03, 2008
    Hello,all I met the question exactly as Kyriakos met.If someone can help me about this,I will be Great appreaciated. Thank all very much

  • Anonymous
    February 25, 2008
    I tried this program in a HP iPAQ Bussines Navigator and always the result is empty. Anyone knows another way to obtain the own phone number? I tried the program with the same SIM Card in a HP 6915 and works fine.

  • Anonymous
    April 07, 2008
    thanks ,starting from your code I can get the imei code using lineGetGeneralInfo().. ;)

  • Anonymous
    March 21, 2009
    Hello, the own phone number (MSISDN) is assigned to mobile station by operator during outgoing call, therefore you can get the number out of SIM only if operator stored it there. Jan