织梦CMS - 轻松建站从此开始!

罗索

同步Windows Mobile SIM卡联系人

jackyhwei 发布于 2010-08-03 10:28 点击:次 
默认情况下,SIM卡中的联系人会同步到contact DB中。这个工作是由cprog.exe(电话程序)来完成,当插卡开机,注册到网络后(或者手机使用中由飞行模式进入待机模式),cprog.exe会删除数据库中带有SIM标志的联系人记录,然后从SIM卡中重新导入。
TAG:

作者:金海建

背景:Windows Mobile默认情况下,SIM卡中的联系人会同步到contact DB中。这个工作是由cprog.exe(电话程序)来完成,当插卡开机,注册到网络后(或者手机使用中由飞行模式进入待机模式),cprog.exe会 删除数据库中带有SIM标志的联系人记录,然后从SIM卡中重新导入。由于项目需要,我们不让cprog.exe运行,那么完成联系人导入的工作,只能交 给自己的程序来处理。

涉及技术: POOM、EDB、SIM API

分析研究: 联系人数据库有四张表,分别是Contact Database、PIMNamedPropTags、PIMNamedPropVals和PINnamedPropValsIndexed

在pim.vol中
     Contact Database数据库:存放联系人数据
0x10000066: 在pimstore.h的定义是PIMPR_OID,这个字段是Contact Database的OID,它会被PIMNamedPropV als和PINnamedPropValsIndexed引用到。比如OID是0x00000001,那么在PIMNamedPropVals的 0x00010013的值就是0x80000001。就是把OID最高位置1,变成PIMNamedPropVals的主键。这就建立了Contact Database、PIMNamedPropVals和PINnamedPropValsIndexed这三张表的关联了。
PIMNamedPropTags 存放扩展的字段,一般用get name的方式来得到其Tag的值.
0x0082001F:在pimstore.h的定义是PIMPR_FIRST_NAME
0x0096001F:在pimstore.h的定义是 PIMPR_MOBILE_TELEPHONE_NUMBER
0x0080001F:在pimstore.h的定义是PIMPR_FILEAS
0x001B0013:在pimstore.h的定义是PIMPR_SOURCE_ID, 表示什么类型的联系人,SIM卡联系人为0。
0x01020013:在pimstore.h的定义是PIMPR_CONTACT_TYPE, 表示是否是SIM卡联系人。1为SIM卡联系人
0x10100013:在pimstore.h的定义是PIMPR_DO_NOT_SYNC, 表示是否通过Activesync同Outlook中的联系人进行同步。SIM卡联系人这个值为零。
其他字段:SIM卡联系人只涉及到上面7个属性值(Property Type)、其他不做解释。
      PIMNamedPropTags数据库: 这个数据库存放系统中没有定义微软没有定义出的Prop Type,而且它的Prop ID会随着不同的环境而不同,所以在写程序的时候,是根据上层提供相应的接口,根据它的Name得到Prop ID。它的每列有三个Prop Type(微软没有定义)。
0x0001001F:Property Name。
0x00020013:Property Name对应的Property ID。
0x00030013:未知,应该是保留的,该属性的值为零。
     如果PINNamedPropTags数据中还没有建立有关SIM卡的Named PropTags。那么就需要自己来建立。我们可以设置一个默认的属性值。创建代码如下:

  1. typedef struct PIMNamedInfo_tag { 
  2.     TCHAR szTagName[128]; 
  3.     DWORD dwTag; 
  4.     DWORD reserve; 
  5. }PIMNamedInfo; 
  6.  
  7. PIMNamedInfo g_defaultSIMNamedInfo[] ={ 
  8.     {TEXT("BusinessTelephoneNumberSimPos"), 0x80020013,0}, 
  9.     {TEXT("Business2TelephoneNumberSimPos"), 0x80030013,0},  
  10.     {TEXT("MobileTelephoneNumberSimPos"), 0x80040013,0}, 
  11.     {TEXT("HomeTelephoneNumberSimPos"), 0x80050013,0}, 
  12.     {TEXT("Home2TelephoneNumberSimPos"), 0x80060013,0}, 
  13.     {TEXT("CarTelephoneNumberSimPos"), 0x80070013,0}, 
  14.     {TEXT("CompanyTelephoneNumberSimPos"), 0x80080013,0}, 
  15.     {TEXT("RadioTelephoneNumberSimPos"), 0x80090013,0}, 
  16.     {TEXT("AssistantTelephoneNumberSimPos"), 0x800A0013,0}, 
  17.     {TEXT("PagerNumberSimPos"), 0x800B0013,0}, 
  18.     {TEXT("BusinessFaxNumberSimPos"), 0x800C0013,0}, 
  19.     {TEXT("HomeFaxNumberSimPos"), 0x800D0013,0}, 
  20.     {TEXT("SIM_INDEX"), 0x800E0013,0} 
  21. }; 
  22.  
  23. BOOL    SetDefaultSIMNamePropTags(){ 
  24.     CEPROPVAL       props[3]; 
  25.     DWORD           dwTotalRecords = 0; 
  26.     CEOID           oidRec; 
  27.     BOOL            fRet = TRUE; 
  28.     if(! m_hPIMNamedPropTagsDB || INVALID_HANDLE_VALUE == m_hPIMNamedPropTagsDB) 
  29.     { 
  30.         goto Cleanup; 
  31.     } 
  32.     DWORD dwTagID = 0x80000013; 
  33.     DWORD dwTagIncress = 0; 
  34.     for (int i=0; i < sizeof(g_defaultSIMNamedInfo)
  35. /sizeof(g_defaultSIMNamedInfo[0]); i++) 
  36.     { 
  37.         ZeroMemory(props, sizeof(props)); 
  38.         props[0].propid = PIMPR_PIMNAMEDTAG_NAME; 
  39.         props[0].val.lpwstr = g_defaultSIMNamedInfo[i].szTagName; 
  40.         dwTagIncress = m_PIMNamedPropTags.size(); 
  41.         g_defaultSIMNamedInfo[i].dwTag = (dwTagID | (dwTagIncress << 16)); 
  42.         props[1].propid = PIMPR_PIMNAMEDTAG_VALUE; 
  43.         props[1].val.ulVal = g_defaultSIMNamedInfo[i].dwTag; 
  44.         props[2].propid = PIMPR_PIMNAMEDTAG_UNKOWN; 
  45.         props[2].val.ulVal = 0; 
  46.         oidRec = CeWriteRecordProps(m_hPIMNamedPropTagsDB, 0, 3, props); 
  47.         if (!(oidRec)) 
  48.         { 
  49.             fRet = FALSE; 
  50.             goto Cleanup; 
  51.         } 
  52.         m_PIMNamedPropTags.push_back(g_defaultSIMNamedInfo[i]); 
  53.     } 
  54. Cleanup: 
  55.     return fRet; 

其中我们同步SIM卡联系人需要用到的有两个Prop。一个是SIM_INDEX,这个就是存放联系人在SIM卡上的Index(索引)。 另一个是MobileTelephoneNumberSimPos, 按照字面意思是电话号码在SIM卡中的位置,大家可以看到上面代码中还有很多XXXSimPos的名字,估计是有些SIM卡的一条联系人可以有多个号码。 用这个Index来表示它的位置。
    PIMNamedPropVals数据库:存储某个联系人Named Prop的值。
0x00010013: 对应与contact中的oid,并把最高位置1。这样就可以根据Contact DB某条记录的oid,到PIMNamedPropVals数据库中找到相应的Named Prop Value了。
0x00020013: 对应PIMNamedPropTags中的Prop ID。
0x00030041: BLOB值,不同Prop有不同的值。其中SIM_INDEX,是一个结构体

typedef struct PIMNAMEDVALUE_INFO_tag
{
    WORD    wIndex;
    WORD    wReserve;
}PIMNAMEDVALUE_INFO;
而MobileTelephoneNumberSimPos,这个值,设置成0就可以了。
PINnamedPropValsIndexed数据库:该数据库作用不是非常大(可有可无),估计是做快速索引用的。
0x00010013: 对应于contact中的oid,最高位为1
0x00020013: 制定该Value的类别,是号码类型,还是其他类型。号码类型,0x00030013设置为0x302A001F
0x00030041: BLOB值,字符串。号码或者email
0x00040013: 是否也存在SIM卡上。

代码示例:
 
  1. void ImportFormSIM(){ 
  2.     HSIM    hSim = NULL; 
  3.     DWORD   dwUsedCount=0; 
  4.     DWORD    dwUsed = 0, dwTotal = 0; 
  5.     SIMPHONEBOOKENTRY simPhoneEntry; 
  6.     if(FAILED(SimInitialize(NULL, NULL,0,&hSim))) 
  7.         goto Error; 
  8.     if(S_OK != SimGetPhonebookStatus(hSim, SIM_PBSTORAGE_SIM,
  9.  &dwUsed, &dwTotal)) 
  10.     { 
  11.         goto Error; 
  12.     } 
  13.     LoadNamedPropTags(); 
  14.     for (int i=1; i <= dwTotal; i++) 
  15.     { 
  16.         if(dwUsedCount >= dwUsed) 
  17.             break
  18.         ZeroMemory(&simPhoneEntry, sizeof(simPhoneEntry)); 
  19.         simPhoneEntry.cbSize = sizeof(simPhoneEntry); 
  20.         if(S_OK == SimReadPhonebookEntry(hSim,
  21.  SIM_PBSTORAGE_SIM, i, &simPhoneEntry)) 
  22.         { 
  23.             DWORD dwOID = WriteSIMContact2DB(&simPhoneEntry, i); 
  24.             dwUsedCount++; 
  25.         } 
  26.     } 
  27. Error: 
  28.     if(hSim) 
  29.         SimDeinitialize(hSim); 
  30.  
  31. BOOL WriteSIMContact2DB(SIMPHONEBOOKENTRY *psimPhoneEntry, int index){ 
  32.     CEPROPVAL       props[6]; 
  33.     DWORD           dwTotalRecords = 0; 
  34.     CEOID           oidRec; 
  35.     BOOL            fRet = TRUE; 
  36.     ZeroMemory(props, sizeof(props)); 
  37.     if(! m_hDB || INVALID_HANDLE_VALUE == m_hDB) 
  38.     { 
  39.         goto Cleanup; 
  40.     } 
  41.     props[0].propid = PIMPR_FILEAS; 
  42.     props[0].val.lpwstr = psimPhoneEntry->lpszText; 
  43.     props[1].propid = PIMPR_FIRST_NAME; 
  44.     props[1].val.lpwstr = psimPhoneEntry->lpszText; 
  45.     props[2].propid = PIMPR_MOBILE_TELEPHONE_NUMBER; 
  46.     props[2].val.lpwstr = psimPhoneEntry->lpszAddress; 
  47.     props[3].propid = PIMPR_CONTACT_TYPE; 
  48.     props[3].val.ulVal = 1; 
  49.     props[4].propid = PIMPR_DO_NOT_SYNC; 
  50.     props[4].val.ulVal = 1; 
  51.     props[5].propid = PIMPR_SOURCE_ID; 
  52.     props[5].val.ulVal = 0; 
  53.     oidRec = CeWriteRecordProps(m_hDB, 0, 6, props); 
  54.     if (!(oidRec)) 
  55.     { 
  56.         fRet = FALSE; 
  57.         goto Cleanup; 
  58.     } 
  59.     CEPROPVAL*pRecord = NULL; 
  60.     WORD   wNumProps = 1 ; 
  61.     DWORD  dwBufSize = 0; 
  62.     CEPROPID propID[1]={PIMPR_OID}; 
  63.     dwBufSize = 0; 
  64.     CeReadRecordPropsEx(m_hDB, 0, &wNumProps, propID,
  65.  (LPBYTE *)&pRecord, &dwBufSize, NULL); 
  66.     pRecord = (CEPROPVAL *) LocalAlloc(0, dwBufSize); 
  67.     CeReadRecordPropsEx(m_hDB, 0, &wNumProps, propID,
  68.  (LPBYTE *)&pRecord, &dwBufSize, NULL); 
  69.     AddnamePropIndexed(pRecord[0].val.ulVal | 0X80000000,
  70.  psimPhoneEntry->lpszAddress); 
  71.     AddNamedPropValues(pRecord[0].val.ulVal | 0X80000000, index); 
  72.     LocalFree(pRecord); 
  73.  
  74. Cleanup: 
  75.     if(fRet) 
  76.         return (pRecord[0].val.ulVal | 0X80000000); 
  77.     else 
  78.         return fRet; 
  79.  
  80. BOOL    AddNamedPropValues(CEOID ceOid, DWORD dwIndex){ 
  81.     CEPROPVAL       props[3]; 
  82.     DWORD           dwTotalRecords = 0; 
  83.     CEOID           oidRec; 
  84.     BOOL            fRet = TRUE; 
  85.     PIMNAMEDVALUE_INFO nameValue; 
  86.     nameValue.wIndex = 0; 
  87.     nameValue.wReserve = 0; 
  88.     ZeroMemory(props, sizeof(props)); 
  89.     if(! m_hDB || INVALID_HANDLE_VALUE == m_hDB) 
  90.     { 
  91.         goto Cleanup; 
  92.     } 
  93.     props[0].propid = PIMPR_PIMNAMEDVALUS_VALUES_OID; 
  94.     props[0].val.ulVal = ceOid; 
  95.     props[1].propid = PIMPR_PIMNAMEDVALUS_VALUES_TAG; 
  96.     props[1].val.ulVal = GetIDOfNames(L"MobileTelephoneNumberSimPos"); 
  97.     props[2].propid = PIMPR_PIMNAMEDVALUS_VALUES_INFO; 
  98.     props[2].val.blob.lpb = (BYTE *)&nameValue; 
  99.     props[2].val.blob.dwCount = sizeof(PIMNAMEDVALUE_INFO); 
  100.     oidRec = CeWriteRecordProps(m_hPIMNamedPropValsDB, 0, 3, props); 
  101.     if (!(oidRec)) 
  102.     { 
  103.         fRet = FALSE; 
  104.         goto Cleanup; 
  105.     } 
  106.     nameValue.wIndex = dwIndex; 
  107.     nameValue.wReserve = 0; 
  108.     props[0].propid = PIMPR_PIMNAMEDVALUS_VALUES_OID; 
  109.     props[0].val.ulVal = ceOid; 
  110.     props[1].propid = PIMPR_PIMNAMEDVALUS_VALUES_TAG; 
  111.     props[1].val.ulVal = GetIDOfNames(L"SIM_INDEX"); 
  112.     props[2].propid = PIMPR_PIMNAMEDVALUS_VALUES_INFO; 
  113.     props[2].val.blob.lpb = (BYTE *)&nameValue; 
  114.     props[2].val.blob.dwCount = sizeof(PIMNAMEDVALUE_INFO); 
  115.     oidRec = CeWriteRecordProps(m_hPIMNamedPropValsDB, 0, 3, props); 
  116.     if (!(oidRec)) 
  117.     { 
  118.         fRet = FALSE; 
  119.         goto Cleanup; 
  120.     } 
  121.  
  122. Cleanup: 
  123.     return fRet; 
OK了。
(jinhaijian)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201008/9922.html]
本文出处:CSDN博客 作者:jinhaijian
顶一下
(1)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容