青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

franksunny的個人技術空間
獲得人生中的成功需要的專注與堅持不懈多過天才與機會。 ——C.W. Wendte

 

Symbian端彩信讀取初探

 

上周由于項目需要對彩信讀取進行了預研,雖然并未涉及彩信的攔截,只是對Symbian S60手機收件箱中的彩信和彩信通知的內容進行提取并分析,但是也算是趟了下之前一直沒有搞過的彩信這渾水,小結一下。為了體現分析過程的邏輯性,下文并非是由簡入繁,而是采用由已知到未知的說明過程來進行。

彩信和彩信通知的區別

正如前面博文《Symbian OS中的消息存儲與常用操作》中提及的那樣,手機中的各種消息都是以數據項(Entry)形式供程序操作,鑒于Nokia之前的SDK有眾多API采用非公開的方式,很多東西碰上了只能拼命的試,試通了就算OK了,短信就是這個樣子的,自從Cxt將發送短信的代碼調通后,目前用的代碼基本都是他那份原型。寫了這么多只想說雖然手機中的各種消息都是以數據項形式給出的,但是數據項又由文件夾類型、消息類型、附件類型和服務類型的數據項,我們所指的消息如短信、彩信和郵箱乃至用戶自定義的一些消息等等都是消息類型的數據項即KuidMsvMessageEntry類型。既然消息類型的數據項這么多,那么如何區分呢,這就靠各自不同的Mtm類型,由于SDK沒有系統性闡述,我們雖然已經知道短信的類型是KUidMsgTypeSMS,但是彩信的Mtm類型值到底是什么,它跟彩信通知是否是有區分的,我們不得而知。

沒辦法只能通過數據項的通用操作,對手機中已存的彩信和彩信通知進行讀取后進行分析內容,才得知彩信和彩信通知是兩個完全不同的Mtm類型值,一個是0x100058E1,另一個是0x100059C8,后來通過google搜索才知道前者的宏定義類型為KuidMsgTypeMultimedia,后者的宏定義類型為KUidMsgMMSNotification,兩者在mmsconst.h頭文件中有定義。

同樣使用通用的數據項操作,我們可以獲取彩信和彩信通知消息數據項的消息存儲CMsvStore和附件情況,兩者的CMsvStore都是有數據的(SizeL()函數返回都是大于0的),但是卻沒有文本體(HasBodyTextL()返回都是Efalse);另外彩信都是有附件的,而彩信通知一般是沒有附件的。

因為附件本身也是數據項(KuidMsvAttachmentEntry類型的數據項),所以我們可以更進一步通過通用的數據項操作將彩信的所有附件全部都讀取出來。而附件類型由文件類型、鏈接類型和數據項類型三種,通常彩信中的附件都是文件類型的附件,我們用以下代碼來演示將附件拷貝出來

CMsvStore* inboxStore= iSmsMtm->Entry().ReadStoreL();

CleanupStack::PushL(inboxStore);

 

MMsvAttachmentManager& attachManager = inboxStore->AttachmentManagerL();

TInt attachmentCount = attachManager.AttachmentCount();

for(TInt i=0;i< attachmentCount;i++)

{

    CMsvAttachment *attachment = attachManager.GetAttachmentInfoL(i);

    CleanupStack::PushL(attachment);

 

    if(type != CMsvAttachment::EMsvMessageEntry)

    {

        TFileName newPath(_L("c:\\data\\"));

        newPath.AppendNum(aMessageId);

        newPath.Append(_L("LLF"));

        newPath.Append(attachment->AttachmentName());

        RFile file = attachManager.GetAttachmentFileL(i);

        TInt size(0);

        file.Size(size);

        HBufC8 *buf = HBufC8::NewLC(size);

        TPtr8 ptrBuf(buf->Des());

        file.Read(ptrBuf, size);

        RFile newFile;

        User::LeaveIfError(newFile.Replace(iFs, newPath, EFileWrite));

        newFile.Write(ptrBuf);

        newFile.Close();

        CleanupStack::PopAndDestroy(buf); 

    }

    CleanupStack::PopAndDestroy();

}

 

CleanupStack::PopAndDestroy();

為了更加直觀的區分各個附件隸屬于不同的消息,為此以消息ID打頭并加LLF來區分附件的各個文件,一條家庭生活報的彩信,我獲取到13個附件的截圖如下

其中有smil文件,有圖片文件,也有文本文件。

使用通用的數據項操作方法,借助SDK我們對彩信和彩信通知的內容區別和內容分析只能到這里了。

 

彩信的內容分析

顯然如果僅僅知道以上內容還是不夠的,困擾我們的CMsvStore里面到底有些什么東西呢?暫時從代碼里面走出去,我們來參閱下Nokia發布的一份難得的中文文檔《CH_How_To_Create_MMS_Services_v4_0.pdf》(詳見附件),正如短信有短信的PDU一樣,彩信也是有其PDU的,這個PDU就在這個文檔的第五部分,在這里就不詳述了,從里面截個圖過來說明下問題。

由這個MMSPDU,我們可以猜想下附件就是Message Body,CMsvStore是否就是MMS Header的內容呢?

幸好現在NokiaSymbian開源了,否則這個猜想是沒有辦法揭開了,通過Symbian網站上的源代碼瀏覽器,我們可以搜到彩信相關的源代碼位于sf\app\messaging文件夾下,但是這個里面除了彩信之外,短信也有,郵箱也有,到底該如何找到需要的彩信呢,我們知道短信其實也有短信頭的,在SDK中有提供CSmsHeader,懷疑彩信也應該有這么頭才是,于是用C*Header搜索文件夾,過來能夠搜索到一個mmsheaders.h頭文件中有一個CMmsHeaders,找到了這個離勝利就不遠了,聯想到短信讀取時有一個CSmsClientMtm::LoadMessageL()函數,索性就找找有沒有一個CMmsClientMtm::LoadMessageL()函數的,通過sf\app\messaging\mmsengine\clientmtm\src文件加下的mmsclient.cpp果然能找到這個函數,其源代碼如下

// ---------------------------------------------------------

// CMmsClientMtm::LoadMessageL

// Loads the multimedia message

// ---------------------------------------------------------

//

void CMmsClientMtm::LoadMessageL()

    {

    // First we should assert that iMsvEntry is not NULL, and panic, if it is

    __ASSERT_DEBUG( iMsvEntry, gPanic( EMmsNoCMsvEntrySet ) );

    // LoadMessageL should only be supported for message entries.

    if ( iMsvEntry->Entry().iType.iUid != KUidMsvMessageEntryValue )

        {

        iAttributes->Reset();

        iMmsHeaders->Reset();

        iAddresseeList->Reset();

        return;       

        }

   

    // Old data must be reset first....

    iAttributes->Reset();

 

    // load the correct data

    // get read-only message store

    CMsvStore* store = iMsvEntry->ReadStoreL();

    CleanupStack::PushL( store );

 

    // restore headers of multimedia message

    // Attachment info is not restored.

    // It makes no sense to cache the attachment info as new attachments

    // can be added with the help of the attachment magager without

    // informing MMS Client MTM of the additions.

    // Caller must use attachment manager to get attachment info.

    iMmsHeaders->RestoreL( *store );

   

    RestoreAttributesL( *store );

   

    CleanupStack::PopAndDestroy( store );

    store = NULL;

 

    // Build the iAddresseeList up

    BuildAddresseeListL();

 

    }

注意源碼中紅色字體部分,我是英盲,所以也不管這個restore是啥意思,直接看CMmsHeaders里面的頭文件定義和源碼

頭文件定義

        /**

        * Internalize the headers.

        * @param aStore CMsvStore

        */

        IMPORT_C void RestoreL( CMsvStore& aStore );

其實看了頭文件里面的定義注釋,初始化頭,參數是CMsvStore我們就知道是怎么回事了,不過既然有源碼,那就還是貼下源碼,至于分析我就不做了,反正跟短信讀取CSmsHeader一樣,操作這個CMmsHeaders

// ---------------------------------------------------------

// CMmsHeaders::RestoreL

//

// ---------------------------------------------------------

//

 

EXPORT_C void CMmsHeaders::RestoreL(

    CMsvStore& aStore )

    {

 

    RMsvReadStream stream;

    Reset( NULL ); // all old pointers are deleted here

    if ( aStore.IsPresentL( KUidMmsHeaderStream ) )

        {

        stream.OpenLC( aStore, KUidMmsHeaderStream ); // pushes 'stream' to the stack

        InternalizeL( stream );

        CleanupStack::PopAndDestroy( &stream ); // close stream

        }

    // restore MMBox header streams if present

    if ( aStore.IsPresentL( KUidMMsElementDescriptorStream ) )

        {

        stream.OpenLC( aStore, KUidMMsElementDescriptorStream ); // pushes 'stream' to the stack

        iElementDescriptor = new( ELeave )CMmsElementDescriptor;

        iElementDescriptor->InternalizeL( stream );

        CleanupStack::PopAndDestroy( &stream ); // close stream

        }

    if ( aStore.IsPresentL( KUidMMsMMBoxMessageHeaderStream ) )

        {

        stream.OpenLC( aStore, KUidMMsMMBoxMessageHeaderStream ); // pushes 'stream' to the stack

        iMmBoxMessageHeaders = CMmsMMBoxMessageHeaders::NewL();

        iMmBoxMessageHeaders->InternalizeL( stream );

        CleanupStack::PopAndDestroy( &stream ); // close stream

        }

    if ( aStore.IsPresentL( KUidMMsMMBoxViewHeadersStream ) )

        {

        stream.OpenLC( aStore, KUidMMsMMBoxViewHeadersStream ); // pushes 'stream' to the stack

        iMmBoxViewHeaders = new( ELeave )CMmsMMBoxViewHeaders;

        iMmBoxViewHeaders->InternalizeL( stream );

        CleanupStack::PopAndDestroy( &stream ); // close stream

        }

 

    // Extended notification also restored here

    TInt length = 0; // string length

 

    // Completeness indicator is not saved or restored.

    // If we have stored the text, it normally indicates that the message is not complete

    if ( aStore.IsPresentL( KUidMMsExtendedNotificationStream ) )

        {

        stream.OpenLC( aStore, KUidMMsExtendedNotificationStream ); // pushes 'stream' to the stack

        length = stream.ReadInt32L();

        if ( length > 0 )

            {

            iExtendedNotificationText = HBufC::NewL( stream, length );

            }

        CleanupStack::PopAndDestroy( &stream ); // close stream

        }

   

    if ( aStore.IsPresentL( KUidMmsApplicationInfoStream ) )

        {

        stream.OpenLC( aStore, KUidMmsApplicationInfoStream ); // pushes 'stream' to the stack

        length = stream.ReadInt32L();

        if ( length > 0 )

            {

            iApplicationId = HBufC::NewL( stream, length );

            }

        length = stream.ReadInt32L();

        if ( length > 0 )

            {

            iReplyToApplicationId = HBufC::NewL( stream, length );

            }

        length = stream.ReadInt32L();

        if ( length > 0 )

            {

            iApplicationInfo = HBufC8::NewL( stream, length );

            }

       

        CleanupStack::PopAndDestroy( &stream ); // close stream

        }

       

    if ( aStore.IsPresentL( KUidMmsReserved ) )

        {

        stream.OpenLC( aStore, KUidMmsReserved ); // pushes 'stream' to the stack

        iRecommendedRetrievalMode = stream.ReadInt32L();

        length = stream.ReadInt32L();

        if ( length > 0 )

            {

            iRecommendedRetrievalModeText = HBufC16::NewL( stream, length );

            }

        length = stream.ReadInt32L();

        if ( length > 0 )

            {

            iReplaceCancelId = HBufC8::NewL( stream, length );

            }

        iCancelStatus = stream.ReadInt32L();

        CleanupStack::PopAndDestroy( &stream ); // close stream

        }

       

    }

一來由于時間倉促,二來開源的代碼頭文件和相關庫等要拷入工程中去,所以具體的編碼調試驗證就留給以后正式要用的時候再進行了。

 

彩信通知的內容分析

以上對彩信的內容分析算是告一個段落了,我們再回過頭來看看這個彩信通知,這個消息類型的數據項其mtmKUidMsgMMSNotification,那么這個客戶端的MTm到底是什么,繼續搜索源碼,發現在sf\app\messaging\mmsengine\clientmtm\src有一個mmsnotificationclient.cpp其內部正好是CmmsNotificationClientMtm。本來以為其會跟彩信一樣比較容易看出結果來,誰知道這個類的源碼看了下,感覺有點殘缺的味道,里面也有用到彩信的頭CMmsHeaders,因為CMmsHeaders就沒有去深入,這下也只能打住了。而且還有一個疑問,如何通過這個彩信通知來編程實現手動去獲取彩信,又是一個比較繁瑣的問題,搜了下源碼貌似跟sf\app\messaging\mobilemessaging\mmsui\notmtmsrc文件下的源碼有關。看來這趟渾水不太清啊,就此打住了。

 

暫時將Symbian端的彩信讀取分析到這里。以后有機會再繼續趟這渾水。

 

按照常規,由于貼圖不會搞,如果需要詳盡文檔,請下載以下word文檔和諾基亞官方文檔rar的鏈接
彩信初探.rar

注意:
目前在6730機子上對草稿箱彩信進行試驗時發現
編輯的彩信假如沒有經過發送,那么通過之前的attachment->AttachmentName()無法獲得附件的文件名;但是在N81等機子上是能夠獲取到的。雖然通過attachment->AttachmentName()無法獲取,但是目前發現通過attachment->FilePath()卻可以得到完整的文件路徑,為此附件文件名的獲取,假設attachment->AttachmentName()獲取不到,那么將采用attachment->FilePath()獲取文件路徑后進行文件名提取的方法來實現比較可靠一些。

posted on 2010-07-28 21:16 frank.sunny 閱讀(2568) 評論(0)  編輯 收藏 引用 所屬分類: symbian 開發

常用鏈接

留言簿(13)

隨筆分類

個人其它博客

基礎知識鏈接

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲欧美日本视频在线观看| 午夜亚洲视频| 久久精品五月婷婷| 国产精品网站在线| 亚洲砖区区免费| 亚洲九九爱视频| 欧美精品尤物在线| 亚洲人在线视频| 91久久精品国产91久久| 久久夜色精品国产噜噜av| 国产视频精品va久久久久久| 亚洲欧美国产高清| 欧美大片在线看免费观看| 亚洲性夜色噜噜噜7777| 美女诱惑一区| 亚洲日本免费电影| 亚洲人成77777在线观看网| 欧美国产在线电影| aaa亚洲精品一二三区| 日韩视频专区| 国产精品一卡| 免费成人av资源网| 欧美激情小视频| 欧美成黄导航| 中文av一区特黄| 翔田千里一区二区| 1769国内精品视频在线播放| 欧美成人免费在线| 欧美激情一二三区| 新片速递亚洲合集欧美合集| 日韩亚洲视频| 欧美日韩国产成人| 欧美一区久久| 免费久久99精品国产| 99在线热播精品免费| 亚洲一区二区成人| 亚洲第一综合天堂另类专| 亚洲欧洲一区| 国产日韩一区二区三区在线播放| 蜜臀a∨国产成人精品| 欧美日韩成人在线| 久久黄色网页| 欧美精品日韩| 久久免费视频在线观看| 欧美精品免费视频| 老司机精品视频网站| 欧美日韩理论| 免费高清在线视频一区·| 欧美国产日韩xxxxx| 亚洲欧美制服中文字幕| 欧美一区二区在线免费播放| 9色精品在线| 久久亚洲精品一区二区| 亚洲欧美国内爽妇网| 久久永久免费| 久久久五月天| 国产精品影音先锋| 亚洲卡通欧美制服中文| 激情久久久久久久| 亚洲永久免费精品| 日韩视频二区| 巨胸喷奶水www久久久免费动漫| 亚洲免费在线观看视频| 欧美大片91| 麻豆91精品| 国产视频一区在线观看一区免费| 日韩一级大片| 99精品福利视频| 久久中文字幕导航| 亚洲香蕉在线观看| 欧美电影在线观看| 欧美成人综合一区| 国产亚洲精品美女| 午夜天堂精品久久久久| 亚洲欧美日韩高清| 欧美日韩亚洲综合| 日韩一二在线观看| 亚洲一区二区三区涩| 欧美日韩亚洲免费| 99国产精品视频免费观看| 亚洲欧洲日本mm| 欧美成人午夜激情| 亚洲盗摄视频| 黄色一区二区在线观看| 欧美有码在线观看视频| 久久嫩草精品久久久久| 国产亚洲一级| 久久嫩草精品久久久精品一| 噜噜噜噜噜久久久久久91| 18成人免费观看视频| 美女露胸一区二区三区| 国产亚洲精品美女| 欧美成人午夜77777| 亚洲福利视频免费观看| 老司机午夜精品| 亚洲国产成人久久综合| 亚洲伦理精品| 欧美日韩大片| 中文成人激情娱乐网| 欧美影院一区| 国产一区高清视频| 久久伊人一区二区| 亚洲大片免费看| 亚洲国产精品悠悠久久琪琪| 欧美激情视频一区二区三区在线播放| 亚洲激情视频网站| 午夜欧美大尺度福利影院在线看| 国产一区二区成人久久免费影院| 久久精品二区| 亚洲精品久久久久中文字幕欢迎你| 一本高清dvd不卡在线观看| 国产精品av久久久久久麻豆网| 亚洲综合激情| 欧美成人一区二区三区片免费| 99国内精品久久| 欧美揉bbbbb揉bbbbb| 香蕉久久夜色精品国产| 欧美激情偷拍| 久久成人资源| 一本久道综合久久精品| 国产欧美大片| 欧美精品一区在线观看| 欧美在线资源| 一区二区毛片| 亚洲高清不卡在线| 日韩视频永久免费观看| 国产精品视频一| 香港成人在线视频| 亚洲精品一区二区三区四区高清 | 亚洲综合三区| 亚洲第一二三四五区| 欧美一区亚洲二区| 99精品欧美一区二区三区| 国产在线精品成人一区二区三区| 欧美在线91| 91久久久在线| 欧美激情1区2区| 久久精品夜色噜噜亚洲a∨| av成人激情| 亚洲国产精品一区二区www在线 | 亚洲黄色大片| 另类激情亚洲| 久久久精品国产一区二区三区| 亚洲私拍自拍| 日韩视频在线免费| 亚洲国产1区| 国外成人性视频| 欧美日韩一区二区三区四区五区| 久久久久久网站| 亚洲精品一区二区三区福利| 亚洲国产成人高清精品| 免播放器亚洲一区| 久久琪琪电影院| 久久久成人精品| 久久精品99国产精品| 羞羞答答国产精品www一本| 夜夜夜久久久| 亚洲天堂av在线免费观看| 亚洲一区在线看| 久久不射中文字幕| 免费91麻豆精品国产自产在线观看| 亚洲高清自拍| 美女诱惑黄网站一区| 欧美韩日高清| 亚洲作爱视频| 欧美在线播放一区| 久久综合久久综合这里只有精品| 欧美fxxxxxx另类| 欧美日韩国产首页在线观看| 国产精品午夜在线观看| 黄网站色欧美视频| 亚洲乱码国产乱码精品精| 亚洲私人影院| 免费高清在线一区| 亚洲深夜福利| 久久性天堂网| 国产精品www994| 加勒比av一区二区| 国产精品99久久久久久久久| 欧美在线视频一区二区三区| 欧美激情导航| 亚洲在线免费| 欧美成人有码| 韩国一区二区在线观看| 99re在线精品| 久久成人精品| 亚洲精品日韩激情在线电影| 欧美一区二区三区另类| 欧美日本在线播放| 黑人一区二区| 亚洲欧美日韩一区二区三区在线观看 | 免费不卡在线观看| 国产欧美日韩在线 | 精品二区视频| 亚洲一区日韩| 亚洲高清久久| 久久久av毛片精品| 国产精品萝li| 中文在线资源观看网站视频免费不卡 | 99国产一区二区三精品乱码|