DBX文件的读取(部分)

//---------------------------------------------------------------------------   
  1.    
  2. #include <vcl.h>   
  3. #pragma hdrstop   
  4.    
  5. #include "Unit1.h"   
  6. #include <Registry.hpp>   
  7. #include <systdate.h>   
  8. //---------------------------------------------------------------------------   
  9. #pragma package(smart_init)   
  10. #pragma resource "*.dfm"   
  11. TForm1 *Form1;   
  12. //---------------------------------------------------------------------------   
  13. __fastcall TForm1::TForm1(TComponent* Owner)   
  14.     : TForm(Owner)   
  15. {   
  16. }   
  17. //---------------------------------------------------------------------------   
  18. TDateTime __fastcall FileTimeToDateTime(double FileTime)   
  19. {   
  20.     FILETIME localtime;   
  21.     SYSTEMTIME systime;   
  22.     ::FileTimeToLocalFileTime((FILETIME*)&FileTime,&localtime);   
  23.     ::FileTimeToSystemTime((FILETIME*)&localtime,&systime);   
  24.     return SystemTimeToDateTime(systime);   
  25. }   
  26.    
  27. AnsiString __fastcall GetOEDirectory(void)   
  28. {   
  29.     AnsiString tmpStr;   
  30.     AnsiString userID;   
  31.     TRegistry *Reg=new TRegistry();   
  32.     Reg->RootKey=HKEY_CURRENT_USER;   
  33.     if(Reg->OpenKey("\\Software\\Microsoft\\Outlook Express",false))   
  34.         tmpStr=Reg->ReadString("Store Root");   
  35.     if(tmpStr==""){   
  36.         if(Reg->OpenKey("\\Identities",false)){   
  37.             userID=Reg->ReadString("Default User ID");   
  38.             if(Reg->OpenKey("\\Identities\\"+userID+"\\Software\\Microsoft\\Outlook Express\\5.0", False))   
  39.                 tmpStr=Reg->ReadString("Store Root");   
  40.         }   
  41.     }   
  42.     Reg->CloseKey();   
  43.     delete Reg;   
  44.     return tmpStr;   
  45. }   
  46.    
  47. void __fastcall GetFileInfo(void)   
  48. {   
  49.     int hcount;   
  50.     if(oeFile==NULL)return;   
  51.     //在编移0xc4处存放的是邮件个数   
  52.     oeFile->Seek(0xc4,soFromBeginning);   
  53.     oeFile->Read(&hcount,sizeof(hcount));   
  54.     finfo.IndexItemsCount=hcount;   
  55. }   
  56.    
  57. void __fastcall ReadFolderInfo(int position,TList* flist)   
  58. {   
  59.     int i;   
  60.     Toe5_FolderInfo* oe5_FolderInfo;   
  61.     THeaderData HeaderData;   
  62.     bool isFolder;   
  63.     int Flags;   
  64.     int DataSize;   
  65.     int Size;   
  66.     char* FlagsBuffer;   
  67.     int* pFlagsBuffer;   
  68.     char* DataBuffer;   
  69.     char* pDataBuffer;   
  70.    
  71.     oeFile->Seek(position, soFromBeginning);   
  72.     oeFile->Read(&HeaderData , sizeof(HeaderData));   
  73.    
  74.     if(position==HeaderData.position){   
  75.         oe5_FolderInfo=new Toe5_FolderInfo();   
  76.         Flags=HeaderData.FlagCount&0xff;   
  77.         DataSize=HeaderData.DataLength-Flags*sizeof(int);   
  78.         Size=sizeof(int)*Flags;   
  79.         FlagsBuffer=new char[Size];   
  80.         oeFile->Read(FlagsBuffer,Size);   
  81.         pFlagsBuffer=(int*)FlagsBuffer;   
  82.         isFolder=false;   
  83.         for(i=0;i<Flags;i++){   
  84.             //如果有某个标识是0x03或0x06就表是是邮件夹   
  85.             if((*pFlagsBuffer)&0xff==0x3||(*pFlagsBuffer)&0xff==0x6)   
  86.                 isFolder==true;   
  87.             if(isFolder)break;   
  88.             pFlagsBuffer++;   
  89.         }   
  90.         if(isFolder){//如果是邮件夹   
  91.             Size=sizeof(char)*DataSize;   
  92.             DataBuffer=new char[Size];   
  93.             oeFile->Read(DataBuffer,Size);   
  94.             pFlagsBuffer=(int*)FlagsBuffer;   
  95.             for(i=0;i<Flags;i++){   
  96.                 pDataBuffer=DataBuffer;   
  97.                 switch(*pDataBuffer){   
  98.                 case 0x2:   
  99.                     pDataBuffer=pDataBuffer+(((*pFlagsBuffer))>>8);   
  100.                     (*oe5_FolderInfo).FolderName=pDataBuffer;   
  101.                     break;   
  102.                 case 0x3:   
  103.                     pDataBuffer=pDataBuffer+(((*pFlagsBuffer))>>8);   
  104.                     (*oe5_FolderInfo).FolderFile=pDataBuffer;   
  105.                     break;   
  106.                 case 0x80:   
  107.                     (*oe5_FolderInfo).FolderID=((*pFlagsBuffer))>>8;   
  108.                     break;   
  109.                 case 0x81:   
  110.                     (*oe5_FolderInfo).ParentFolderID=((*pFlagsBuffer))>>8;   
  111.                     break;   
  112.                 }   
  113.                 pFlagsBuffer++;   
  114.             }   
  115.             delete []DataBuffer;   
  116.             flist->Add(oe5_FolderInfo);//将邮件夹信息加入列表中   
  117.         }else{   
  118.             delete oe5_FolderInfo;   
  119.         }   
  120.         delete []FlagsBuffer;   
  121.     }   
  122. }   
  123.    
  124. AnsiString __fastcall ReadHeaderInfo(AnsiString FileName,int position)   
  125. {   
  126.     AnsiString Str;   
  127.     int i;   
  128.     THeaderData HeaderData;   
  129.     int Flags;   
  130.     int DataSize;   
  131.     int Size;   
  132.     char* FlagsBuffer;   
  133.     int* pFlagsBuffer;   
  134.     char* DataBuffer;   
  135.     char* pDataBuffer;   
  136.     AnsiString line1;   
  137.     AnsiString line2;   
  138.     char x;   
  139.     int count;   
  140.    
  141.     oeFile=new TFileStream(GetOEDirectory()+"\\"+FileName,fmOpenRead|fmShareDenyNone);   
  142.     oeFile->Seek(position, soFromBeginning);   
  143.     oeFile->Read(&HeaderData , sizeof(HeaderData));   
  144.     if(position==HeaderData.position){   
  145.         Flags=HeaderData.FlagCount&0xff;   
  146.         DataSize=HeaderData.DataLength-(Flags * sizeof(DWORD));   
  147.         Size=sizeof(DWORD)*Flags;   
  148.         FlagsBuffer=new char[Size];   
  149.         oeFile->Read(FlagsBuffer,Size);   
  150.         Size=sizeof(char)*DataSize;   
  151.         DataBuffer=new char[Size];   
  152.         oeFile->Read(DataBuffer,Size);   
  153.         pFlagsBuffer=(int*)FlagsBuffer;   
  154.         Str+="Flags="+AnsiString(Flags)+"\n\n";   
  155.         for(i=0;i<Flags;i++){   
  156.             Str+=AnsiString((*pFlagsBuffer)&0xff)+":"+AnsiString((*pFlagsBuffer)>>8);   
  157.             switch((*pFlagsBuffer)&0xff){   
  158.             case 0x1: Str=Str+" ==> Offset to Message Flags";break;   
  159.             case 0x2: Str=Str+" ==> Sent Date";break;   
  160.             case 0x3: Str=Str+" ==> Filename";break;   
  161.             case 0x5: Str=Str+" ==> Subject";break;   
  162.             case 0x4: Str=Str+" ==> Message position";break;   
  163.             case 0x6: break;   
  164.             case 0x7: Str=Str+" ==> Message-ID";break;   
  165.             case 0x8: Str=Str+" ==> Subject";break;   
  166.             case 0x9: Str=Str+" ==> From:";break;   
  167.             case 0xA: Str=Str+" ==> References";break;   
  168.             case 0xB: Str=Str+" ==> Newsgroup";break;   
  169.             case 0xD: Str=Str+" ==> From:";break;   
  170.             case 0xE: Str=Str+" ==> Reply-To:";break;   
  171.             case 0x12: Str=Str+" ==> Received Date";break;   
  172.             case 0x13: Str=Str+" ==> To:";break;   
  173.             case 0x14: break;   
  174.             case 0x1A: Str=Str+" ==> Account";break;   
  175.             case 0x1B: Str=Str+" ==> Account-ID";break;   
  176.             case 0x80: Str=Str+" ==> Message Number";break;   
  177.             case 0x81: Str=Str+" ==> Message Status";break;   
  178.             case 0x84: Str=Str+" ==> Message Position";break;   
  179.             case 0x91: Str=Str+" ==> Message size";break;   
  180.             }   
  181.             Str=Str+"\n";   
  182.             pFlagsBuffer++;   
  183.         }   
  184.         Str=Str+"\nSize of Header = "+AnsiString(Size)+"\n";   
  185.     }   
  186.     delete []DataBuffer;   
  187.     delete []FlagsBuffer;   
  188.     delete oeFile;   
  189.     oeFile=NULL;   
  190.     return Str;   
  191. }   
  192.    
  193.    
  194. void __fastcall ReadMessageInfo(int position,TList* flist)   
  195. {   
  196.     int i;   
  197.     Toe5_MessageInfo* oe5_MessageInfo;   
  198.     THeaderData HeaderData;   
  199.     int Flags;   
  200.     int DataSize;   
  201.     int Size;   
  202.     char* FlagsBuffer;   
  203.     int* pFlagsBuffer;   
  204.     char* DataBuffer;   
  205.     char* pDataBuffer;   
  206.    
  207.     oeFile->Seek(position, soFromBeginning);   
  208.     oeFile->Read(&HeaderData , sizeof(HeaderData));   
  209.     if(position == HeaderData.position){   
  210.         oe5_MessageInfo=new Toe5_MessageInfo();   
  211.         ZeroMemory(oe5_MessageInfo, sizeof(Toe5_MessageInfo));   
  212.         (*oe5_MessageInfo).HeaderPosition=position;   
  213.         Flags=HeaderData.FlagCount&0xff;//元素个数   
  214.         //总长度减去字段偏移量表的长度就是实际数据长度   
  215.         DataSize=HeaderData.DataLength-(Flags * sizeof(DWORD));   
  216.         Size=sizeof(DWORD)*Flags;//FLAG是4字节整数=3字节偏移量+1字节标识   
  217.         FlagsBuffer=new char[Size];   
  218.         oeFile->Read(FlagsBuffer, Size);//读取偏移量表   
  219.         Size=sizeof(Byte)*DataSize;   
  220.         DataBuffer=new char[Size];   
  221.         oeFile->Read(DataBuffer, Size);//读取邮件元素数据   
  222.         pFlagsBuffer=(int*)FlagsBuffer;   
  223.         //pFlagsBuffer指向的高三位字节是元素内容   
  224.         //所以要执行(*pFlagsBuffer)>>8的操作   
  225.         for(i=0;i<Flags;i++){   
  226.             pDataBuffer=DataBuffer;   
  227.             switch((*pFlagsBuffer)&0xff/*最低位字节是元素类别标识*/){   
  228.             case 0x1:   
  229.                 pDataBuffer+=(*pFlagsBuffer)>>8;   
  230.                 (*oe5_MessageInfo).MsgFlags=*pDataBuffer;   
  231.                 pDataBuffer++;   
  232.                 (*oe5_MessageInfo).MsgFlags=(*oe5_MessageInfo).MsgFlags+(*pDataBuffer)*256;   
  233.                 pDataBuffer++;   
  234.                 (*oe5_MessageInfo).MsgFlags=(*oe5_MessageInfo).MsgFlags+(*pDataBuffer)*65536;   
  235.                 break;   
  236.             case 0x2:   
  237.                 pDataBuffer+=(*pFlagsBuffer)>>8;   
  238.                 (*oe5_MessageInfo).Sent=*(double*)pDataBuffer;   
  239.                 break;   
  240.             case 0x4:   
  241.                 pDataBuffer+=(*pFlagsBuffer)>>8;   
  242.                 (*oe5_MessageInfo).position=*(int*)pDataBuffer;   
  243.                 break;   
  244.             case 0x12:   
  245.                 pDataBuffer+=(*pFlagsBuffer)>>8;   
  246.                 (*oe5_MessageInfo).Received=*(double*)pDataBuffer;   
  247.                 break;   
  248.             case 0x7:   
  249.                 pDataBuffer+=(*pFlagsBuffer)>>8;   
  250.                 (*oe5_MessageInfo).MessageID=pDataBuffer;   
  251.                 break;   
  252.             case 0x8:   
  253.                 pDataBuffer+=(*pFlagsBuffer)>>8;   
  254.                 (*oe5_MessageInfo).Subject=pDataBuffer;   
  255.                 break;   
  256.             case 0x9:   
  257.                 pDataBuffer+=(*pFlagsBuffer)>>8;   
  258.                 (*oe5_MessageInfo).From_Reply=pDataBuffer;   
  259.                 break;   
  260.             case 0xA:   
  261.                 pDataBuffer+=(*pFlagsBuffer)>>8;   
  262.                 (*oe5_MessageInfo).References=pDataBuffer;   
  263.                 break;   
  264.             case 0xB:  // Newsgroup   
  265.                 pDataBuffer+=(*pFlagsBuffer)>>8;   
  266.                 (*oe5_MessageInfo).NewsGroup=pDataBuffer;   
  267.                 break;   
  268.             case 0xD:   // From   
  269.                 pDataBuffer+=(*pFlagsBuffer)>>8;   
  270.                 (*oe5_MessageInfo).From=pDataBuffer;   
  271.                 break;   
  272.             case 0xE:  // Reply to   
  273.                 pDataBuffer+=(*pFlagsBuffer)>>8;   
  274.                 (*oe5_MessageInfo).Reply_To=pDataBuffer;   
  275.                 break;   
  276.             case 0x13:  // Receipt (to:)   
  277.                 pDataBuffer+=(*pFlagsBuffer)>>8;   
  278.                 (*oe5_MessageInfo).Receipt=pDataBuffer;   
  279.                 break;   
  280.             case 0x1A:  // Account   
  281.                 pDataBuffer+=(*pFlagsBuffer)>>8;   
  282.                 (*oe5_MessageInfo).Account=pDataBuffer;   
  283.                 break;   
  284.             case 0x1B:  // Account ID   
  285.                 pDataBuffer+=(*pFlagsBuffer)>>8;   
  286.                 (*oe5_MessageInfo).AccountID=pDataBuffer;   
  287.                 break;   
  288.             case 0x80:   
  289.                 (*oe5_MessageInfo).Msg=(*pFlagsBuffer)>>8; //Message number   
  290.                 break;   
  291.             case 0x81:   
  292.                 (*oe5_MessageInfo).MsgFlags=(*pFlagsBuffer)>>8;  // Message Flags   
  293.                 break;   
  294.             case 0x84:   
  295.                 (*oe5_MessageInfo).position=(*pFlagsBuffer)>>8;  // Position   
  296.                 break;   
  297.             case 0x91:   
  298.                 (*oe5_MessageInfo).size=(*pFlagsBuffer)>>8;  // SIZE??   
  299.                 break;   
  300.             }   
  301.             pFlagsBuffer++;   
  302.         }   
  303.         delete []DataBuffer;   
  304.         flist->Add(oe5_MessageInfo);//将读出的邮件写入列表。   
  305.         delete []FlagsBuffer;   
  306.     }   
  307. }   
  308.    
  309.    
  310. void __fastcall ReadIndex(int position,TList* flist,bool folders)   
  311. {   
  312.     Toe5_IndexHeader iheader;   
  313.     int icount;   
  314.     Toe5_IndexItem* pIndexItem;   
  315.     int i;   
  316.     int Size;   
  317.     char* Buffer;   
  318.    
  319.     if( oeFile !=NULL ){   
  320.         oeFile->Seek(position, soFromBeginning);   
  321.         oeFile->Read(&iheader, sizeof(iheader));   
  322.         //索引头的地址与FilePos地址必须一致   
  323.         if (iheader.FilePos == position ){   
  324.             tmpList->Add((void*)position);   
  325.             if (iheader.NextIndex > 0)   
  326.                 if (tmpList->IndexOf((void*)iheader.NextIndex)==-1)   
  327.                     ReadIndex(iheader.NextIndex,flist,folders);   
  328.             if (iheader.PrevIndex > 0)   
  329.                 if (tmpList->IndexOf((void*)iheader.PrevIndex)==-1)   
  330.                     ReadIndex(iheader.PrevIndex,flist,folders);   
  331.    
  332.             //索引表中的记录个数,每条记录表示一封邮件   
  333.             icount=iheader.Count>>8;   
  334.             if (icount > 0){   
  335.                 Size=sizeof(Toe5_IndexItem)*icount;   
  336.                 Buffer=new char[Size];   
  337.                 //紧接着索引表的后面就是该表记录,表记录的个数由索引头的Count值确定   
  338.                 oeFile->Seek(iheader.FilePos + sizeof(iheader), soFromBeginning);   
  339.                 oeFile->Read(Buffer, Size);//读取所有的索引项   
  340.                 pIndexItem=(Toe5_IndexItem*)Buffer;   
  341.                 //逐个读取表记录   
  342.                 for (i=0;i<icount;i++){   
  343.                     if ((*pIndexItem).HeaderPos > 0){   
  344.                         if (folders)   
  345.                             ReadFolderInfo((*pIndexItem).HeaderPos,flist);   
  346.                         else   
  347.                             ReadMessageInfo((*pIndexItem).HeaderPos,flist);   
  348.                     }   
  349.                     if ((*pIndexItem).ChildIndex > 0){   
  350.                         //有些pIndexItem记录包括子邮件记录表   
  351.                         if (tmpList->IndexOf((void*)(*pIndexItem).ChildIndex)==-1)   
  352.                             ReadIndex((*pIndexItem).ChildIndex,flist,folders);   
  353.                     }   
  354.                     pIndexItem++;   
  355.                 }   
  356.                 delete []Buffer;   
  357.             }   
  358.         }   
  359.     }   
  360. }   
  361.    
  362. //===================================================================================   
  363. AnsiString __fastcall Read_OE_Message(AnsiString FileName,int position)   
  364. {   
  365.     Toe5_MsgItem oe5_MsgItem;   
  366.     AnsiString msg;   
  367.     if(position>0){   
  368.         oeFile=new TFileStream(GetOEDirectory()+"\\"+FileName,fmOpenRead|fmShareDenyNone);   
  369.         GetFileInfo();   
  370.         msg="";   
  371.         if (finfo.IndexItemsCount > 0){   
  372.             oeFile->Seek(position, soFromBeginning);   
  373.             while(1){   
  374.                 oeFile->Read(&oe5_MsgItem, sizeof(Toe5_MsgItem));   
  375.                 if (oe5_MsgItem.FilePos != position)break;   
  376.                 msg=msg + oe5_MsgItem.MsgContent;   
  377.                 position=oe5_MsgItem.NextItem;   
  378.                 if (position == 0)break;   
  379.                 oeFile->Seek(position, soFromBeginning);   
  380.             }   
  381.         }   
  382.         delete oeFile;   
  383.     }   
  384.     return msg;   
  385. }   
  386.    
  387. //===================================================================================   
  388.    
  389. void __fastcall Read_OE_File(AnsiString FileName, TList* flist)   
  390. {   
  391.     int position;   
  392.    
  393.     if (flist !=NULL){   
  394.         oeFile=new TFileStream(GetOEDirectory()+"\\"+FileName, fmOpenRead|fmShareDenyNone);   
  395.         GetFileInfo();   
  396.         if (finfo.IndexItemsCount > 0){   
  397.             tmpList=new TList();   
  398.             //第一个索引表头结构位于0x30处   
  399.             oeFile->Seek(0x30, soFromBeginning);   
  400.             oeFile->Read(&position, sizeof(position));   
  401.             ReadIndex(position,flist,FileName=="folders.dbx");   
  402.             delete tmpList;   
  403.         }   
  404.         delete oeFile;   
  405.     }   
  406. }   
  407.    
  408. void __fastcall TForm1::Button1Click(TObject *Sender)   
  409. {   
  410.     TList* flist=new TList();   
  411.     //读取邮件   
  412.     Read_OE_File("收件箱.dbx",flist);   
  413.     if(ClientDataSet1->Active)ClientDataSet1->Close();   
  414.     ClientDataSet1->CreateDataSet();   
  415.     Toe5_MessageInfo* oe5_MessageInfo;   
  416.    
  417.     for(int i=0;i<flist->Count;i++){   
  418.         ClientDataSet1->Append();   
  419.         oe5_MessageInfo=(Toe5_MessageInfo*)flist->Items[i];   
  420.         ClientDataSet1->FieldByName("Msg")->AsInteger=oe5_MessageInfo->Msg;   
  421.         ClientDataSet1->FieldByName("MsgFlags")->AsInteger=oe5_MessageInfo->MsgFlags;   
  422.         ClientDataSet1->FieldByName("AccountID")->AsString=oe5_MessageInfo->AccountID;   
  423.         ClientDataSet1->FieldByName("Account")->AsString=oe5_MessageInfo->Account;   
  424.         ClientDataSet1->FieldByName("MessageID")->AsString=oe5_MessageInfo->MessageID;   
  425.         ClientDataSet1->FieldByName("Sent")->AsDateTime=FileTimeToDateTime(oe5_MessageInfo->Sent);   
  426.         ClientDataSet1->FieldByName("Received")->AsDateTime=FileTimeToDateTime(oe5_MessageInfo->Received);   
  427.         ClientDataSet1->FieldByName("Subject")->AsString=oe5_MessageInfo->Subject;   
  428.         ClientDataSet1->FieldByName("From")->AsString=oe5_MessageInfo->From;   
  429.         ClientDataSet1->FieldByName("From_Reply")->AsString=oe5_MessageInfo->From_Reply;   
  430.         ClientDataSet1->FieldByName("Receipt")->AsString=oe5_MessageInfo->Receipt;   
  431.         ClientDataSet1->FieldByName("Reply_To")->AsString=oe5_MessageInfo->Reply_To;   
  432.         ClientDataSet1->FieldByName("References")->AsString=oe5_MessageInfo->References;   
  433.         ClientDataSet1->FieldByName("NewsGroup")->AsString=oe5_MessageInfo->NewsGroup;   
  434.         ClientDataSet1->FieldByName("Size")->AsInteger=oe5_MessageInfo->size;   
  435.         ClientDataSet1->FieldByName("Position")->AsInteger=oe5_MessageInfo->position;   
  436.         ClientDataSet1->FieldByName("HeaderPosition")->AsInteger=oe5_MessageInfo->HeaderPosition;   
  437.         ClientDataSet1->Post();   
  438.         delete oe5_MessageInfo;   
  439.     }   
  440.     delete flist;   
  441. }   
  442. //---------------------------------------------------------------------------   
  443.    
  444. void __fastcall TForm1::Button2Click(TObject *Sender)   
  445. {   
  446.     Memo1->Lines->Text=Read_OE_Message("收件箱.dbx",ClientDataSet1->FieldByName("Position")->AsInteger);   
  447. }   
  448. //---------------------------------------------------------------------------   
  449.    
  450. void __fastcall TForm1::Button3Click(TObject *Sender)   
  451. {   
  452.     if(SaveDialog1->Execute()){   
  453.         Memo1->Lines->SaveToFile(SaveDialog1->FileName);   
  454.     }   
  455. }   
  456. //---------------------------------------------------------------------------   
  457.    
//--------------------------------------------------------------------------- 
 
#include <vcl.h> 
#pragma hdrstop 
 
#include "Unit1.h" 
#include <Registry.hpp> 
#include <systdate.h> 
//--------------------------------------------------------------------------- 
#pragma package(smart_init) 
#pragma resource "*.dfm" 
TForm1 *Form1; 
//--------------------------------------------------------------------------- 
__fastcall TForm1::TForm1(TComponent* Owner) 
    : TForm(Owner) 
{ 
} 
//--------------------------------------------------------------------------- 
TDateTime __fastcall FileTimeToDateTime(double FileTime) 
{ 
    FILETIME localtime; 
    SYSTEMTIME systime; 
    ::FileTimeToLocalFileTime((FILETIME*)&FileTime,&localtime); 
    ::FileTimeToSystemTime((FILETIME*)&localtime,&systime); 
    return SystemTimeToDateTime(systime); 
} 
 
AnsiString __fastcall GetOEDirectory(void) 
{ 
    AnsiString tmpStr; 
    AnsiString userID; 
    TRegistry *Reg=new TRegistry(); 
    Reg->RootKey=HKEY_CURRENT_USER; 
    if(Reg->OpenKey("\\Software\\Microsoft\\Outlook Express",false)) 
        tmpStr=Reg->ReadString("Store Root"); 
    if(tmpStr==""){ 
        if(Reg->OpenKey("\\Identities",false)){ 
            userID=Reg->ReadString("Default User ID"); 
            if(Reg->OpenKey("\\Identities\\"+userID+"\\Software\\Microsoft\\Outlook Express\\5.0", False)) 
                tmpStr=Reg->ReadString("Store Root"); 
        } 
    } 
    Reg->CloseKey(); 
    delete Reg; 
    return tmpStr; 
} 
 
void __fastcall GetFileInfo(void) 
{ 
    int hcount; 
    if(oeFile==NULL)return; 
    //在编移0xc4处存放的是邮件个数 
    oeFile->Seek(0xc4,soFromBeginning); 
    oeFile->Read(&hcount,sizeof(hcount)); 
    finfo.IndexItemsCount=hcount; 
} 
 
void __fastcall ReadFolderInfo(int position,TList* flist) 
{ 
    int i; 
    Toe5_FolderInfo* oe5_FolderInfo; 
    THeaderData HeaderData; 
    bool isFolder; 
    int Flags; 
    int DataSize; 
    int Size; 
    char* FlagsBuffer; 
    int* pFlagsBuffer; 
    char* DataBuffer; 
    char* pDataBuffer; 
 
    oeFile->Seek(position, soFromBeginning); 
    oeFile->Read(&HeaderData , sizeof(HeaderData)); 
 
    if(position==HeaderData.position){ 
        oe5_FolderInfo=new Toe5_FolderInfo(); 
        Flags=HeaderData.FlagCount&0xff; 
        DataSize=HeaderData.DataLength-Flags*sizeof(int); 
        Size=sizeof(int)*Flags; 
        FlagsBuffer=new char[Size]; 
        oeFile->Read(FlagsBuffer,Size); 
        pFlagsBuffer=(int*)FlagsBuffer; 
        isFolder=false; 
        for(i=0;i<Flags;i++){ 
        	//如果有某个标识是0x03或0x06就表是是邮件夹 
            if((*pFlagsBuffer)&0xff==0x3||(*pFlagsBuffer)&0xff==0x6) 
                isFolder==true; 
            if(isFolder)break; 
            pFlagsBuffer++; 
        } 
        if(isFolder){//如果是邮件夹 
            Size=sizeof(char)*DataSize; 
            DataBuffer=new char[Size]; 
            oeFile->Read(DataBuffer,Size); 
            pFlagsBuffer=(int*)FlagsBuffer; 
            for(i=0;i<Flags;i++){ 
                pDataBuffer=DataBuffer; 
                switch(*pDataBuffer){ 
                case 0x2: 
                    pDataBuffer=pDataBuffer+(((*pFlagsBuffer))>>8); 
                    (*oe5_FolderInfo).FolderName=pDataBuffer; 
                    break; 
                case 0x3: 
                    pDataBuffer=pDataBuffer+(((*pFlagsBuffer))>>8); 
                    (*oe5_FolderInfo).FolderFile=pDataBuffer; 
                    break; 
                case 0x80: 
                    (*oe5_FolderInfo).FolderID=((*pFlagsBuffer))>>8; 
                    break; 
                case 0x81: 
                    (*oe5_FolderInfo).ParentFolderID=((*pFlagsBuffer))>>8; 
                    break; 
                } 
                pFlagsBuffer++; 
            } 
            delete []DataBuffer; 
            flist->Add(oe5_FolderInfo);//将邮件夹信息加入列表中 
        }else{ 
            delete oe5_FolderInfo; 
        } 
        delete []FlagsBuffer; 
    } 
} 
 
AnsiString __fastcall ReadHeaderInfo(AnsiString FileName,int position) 
{ 
    AnsiString Str; 
    int i; 
    THeaderData HeaderData; 
    int Flags; 
    int DataSize; 
    int Size; 
    char* FlagsBuffer; 
    int* pFlagsBuffer; 
    char* DataBuffer; 
    char* pDataBuffer; 
    AnsiString line1; 
    AnsiString line2; 
    char x; 
    int count; 
 
    oeFile=new TFileStream(GetOEDirectory()+"\\"+FileName,fmOpenRead|fmShareDenyNone); 
    oeFile->Seek(position, soFromBeginning); 
    oeFile->Read(&HeaderData , sizeof(HeaderData)); 
    if(position==HeaderData.position){ 
        Flags=HeaderData.FlagCount&0xff; 
        DataSize=HeaderData.DataLength-(Flags * sizeof(DWORD)); 
        Size=sizeof(DWORD)*Flags; 
        FlagsBuffer=new char[Size]; 
        oeFile->Read(FlagsBuffer,Size); 
        Size=sizeof(char)*DataSize; 
        DataBuffer=new char[Size]; 
        oeFile->Read(DataBuffer,Size); 
        pFlagsBuffer=(int*)FlagsBuffer; 
        Str+="Flags="+AnsiString(Flags)+"\n\n"; 
        for(i=0;i<Flags;i++){ 
            Str+=AnsiString((*pFlagsBuffer)&0xff)+":"+AnsiString((*pFlagsBuffer)>>8); 
            switch((*pFlagsBuffer)&0xff){ 
            case 0x1: Str=Str+" ==> Offset to Message Flags";break; 
            case 0x2: Str=Str+" ==> Sent Date";break; 
            case 0x3: Str=Str+" ==> Filename";break; 
            case 0x5: Str=Str+" ==> Subject";break; 
            case 0x4: Str=Str+" ==> Message position";break; 
            case 0x6: break; 
            case 0x7: Str=Str+" ==> Message-ID";break; 
            case 0x8: Str=Str+" ==> Subject";break; 
            case 0x9: Str=Str+" ==> From:";break; 
            case 0xA: Str=Str+" ==> References";break; 
            case 0xB: Str=Str+" ==> Newsgroup";break; 
            case 0xD: Str=Str+" ==> From:";break; 
            case 0xE: Str=Str+" ==> Reply-To:";break; 
            case 0x12: Str=Str+" ==> Received Date";break; 
            case 0x13: Str=Str+" ==> To:";break; 
            case 0x14: break; 
            case 0x1A: Str=Str+" ==> Account";break; 
            case 0x1B: Str=Str+" ==> Account-ID";break; 
            case 0x80: Str=Str+" ==> Message Number";break; 
            case 0x81: Str=Str+" ==> Message Status";break; 
            case 0x84: Str=Str+" ==> Message Position";break; 
            case 0x91: Str=Str+" ==> Message size";break; 
            } 
            Str=Str+"\n"; 
            pFlagsBuffer++; 
        } 
        Str=Str+"\nSize of Header = "+AnsiString(Size)+"\n"; 
    } 
    delete []DataBuffer; 
    delete []FlagsBuffer; 
    delete oeFile; 
    oeFile=NULL; 
    return Str; 
} 
 
 
void __fastcall ReadMessageInfo(int position,TList* flist) 
{ 
    int i; 
    Toe5_MessageInfo* oe5_MessageInfo; 
    THeaderData HeaderData; 
    int Flags; 
    int DataSize; 
    int Size; 
    char* FlagsBuffer; 
    int* pFlagsBuffer; 
    char* DataBuffer; 
    char* pDataBuffer; 
 
    oeFile->Seek(position, soFromBeginning); 
    oeFile->Read(&HeaderData , sizeof(HeaderData)); 
    if(position == HeaderData.position){ 
        oe5_MessageInfo=new Toe5_MessageInfo(); 
        ZeroMemory(oe5_MessageInfo, sizeof(Toe5_MessageInfo)); 
        (*oe5_MessageInfo).HeaderPosition=position; 
        Flags=HeaderData.FlagCount&0xff;//元素个数 
        //总长度减去字段偏移量表的长度就是实际数据长度 
        DataSize=HeaderData.DataLength-(Flags * sizeof(DWORD)); 
        Size=sizeof(DWORD)*Flags;//FLAG是4字节整数=3字节偏移量+1字节标识 
        FlagsBuffer=new char[Size]; 
        oeFile->Read(FlagsBuffer, Size);//读取偏移量表 
        Size=sizeof(Byte)*DataSize; 
        DataBuffer=new char[Size]; 
        oeFile->Read(DataBuffer, Size);//读取邮件元素数据 
        pFlagsBuffer=(int*)FlagsBuffer; 
		//pFlagsBuffer指向的高三位字节是元素内容 
		//所以要执行(*pFlagsBuffer)>>8的操作 
        for(i=0;i<Flags;i++){ 
            pDataBuffer=DataBuffer; 
            switch((*pFlagsBuffer)&0xff/*最低位字节是元素类别标识*/){ 
            case 0x1: 
                pDataBuffer+=(*pFlagsBuffer)>>8; 
                (*oe5_MessageInfo).MsgFlags=*pDataBuffer; 
                pDataBuffer++; 
                (*oe5_MessageInfo).MsgFlags=(*oe5_MessageInfo).MsgFlags+(*pDataBuffer)*256; 
                pDataBuffer++; 
                (*oe5_MessageInfo).MsgFlags=(*oe5_MessageInfo).MsgFlags+(*pDataBuffer)*65536; 
                break; 
            case 0x2: 
                pDataBuffer+=(*pFlagsBuffer)>>8; 
                (*oe5_MessageInfo).Sent=*(double*)pDataBuffer; 
                break; 
            case 0x4: 
                pDataBuffer+=(*pFlagsBuffer)>>8; 
                (*oe5_MessageInfo).position=*(int*)pDataBuffer; 
                break; 
            case 0x12: 
                pDataBuffer+=(*pFlagsBuffer)>>8; 
                (*oe5_MessageInfo).Received=*(double*)pDataBuffer; 
                break; 
            case 0x7: 
                pDataBuffer+=(*pFlagsBuffer)>>8; 
                (*oe5_MessageInfo).MessageID=pDataBuffer; 
                break; 
            case 0x8: 
                pDataBuffer+=(*pFlagsBuffer)>>8; 
                (*oe5_MessageInfo).Subject=pDataBuffer; 
                break; 
            case 0x9: 
                pDataBuffer+=(*pFlagsBuffer)>>8; 
                (*oe5_MessageInfo).From_Reply=pDataBuffer; 
                break; 
            case 0xA: 
                pDataBuffer+=(*pFlagsBuffer)>>8; 
                (*oe5_MessageInfo).References=pDataBuffer; 
                break; 
            case 0xB:  // Newsgroup 
                pDataBuffer+=(*pFlagsBuffer)>>8; 
                (*oe5_MessageInfo).NewsGroup=pDataBuffer; 
                break; 
            case 0xD:   // From 
                pDataBuffer+=(*pFlagsBuffer)>>8; 
                (*oe5_MessageInfo).From=pDataBuffer; 
                break; 
            case 0xE:  // Reply to 
                pDataBuffer+=(*pFlagsBuffer)>>8; 
                (*oe5_MessageInfo).Reply_To=pDataBuffer; 
                break; 
            case 0x13:  // Receipt (to:) 
                pDataBuffer+=(*pFlagsBuffer)>>8; 
                (*oe5_MessageInfo).Receipt=pDataBuffer; 
                break; 
            case 0x1A:  // Account 
                pDataBuffer+=(*pFlagsBuffer)>>8; 
                (*oe5_MessageInfo).Account=pDataBuffer; 
                break; 
            case 0x1B:  // Account ID 
                pDataBuffer+=(*pFlagsBuffer)>>8; 
                (*oe5_MessageInfo).AccountID=pDataBuffer; 
                break; 
            case 0x80: 
                (*oe5_MessageInfo).Msg=(*pFlagsBuffer)>>8; //Message number 
                break; 
            case 0x81: 
                (*oe5_MessageInfo).MsgFlags=(*pFlagsBuffer)>>8;  // Message Flags 
                break; 
            case 0x84: 
                (*oe5_MessageInfo).position=(*pFlagsBuffer)>>8;  // Position 
                break; 
            case 0x91: 
                (*oe5_MessageInfo).size=(*pFlagsBuffer)>>8;  // SIZE?? 
                break; 
            } 
            pFlagsBuffer++; 
        } 
        delete []DataBuffer; 
        flist->Add(oe5_MessageInfo);//将读出的邮件写入列表。 
        delete []FlagsBuffer; 
    } 
} 
 
 
void __fastcall ReadIndex(int position,TList* flist,bool folders) 
{ 
    Toe5_IndexHeader iheader; 
    int icount; 
    Toe5_IndexItem* pIndexItem; 
    int i; 
    int Size; 
    char* Buffer; 
 
    if( oeFile !=NULL ){ 
        oeFile->Seek(position, soFromBeginning); 
        oeFile->Read(&iheader, sizeof(iheader)); 
        //索引头的地址与FilePos地址必须一致 
        if (iheader.FilePos == position ){ 
            tmpList->Add((void*)position); 
            if (iheader.NextIndex > 0) 
                if (tmpList->IndexOf((void*)iheader.NextIndex)==-1) 
                    ReadIndex(iheader.NextIndex,flist,folders); 
            if (iheader.PrevIndex > 0) 
                if (tmpList->IndexOf((void*)iheader.PrevIndex)==-1) 
                    ReadIndex(iheader.PrevIndex,flist,folders); 
 
			//索引表中的记录个数,每条记录表示一封邮件 
            icount=iheader.Count>>8; 
            if (icount > 0){ 
                Size=sizeof(Toe5_IndexItem)*icount; 
                Buffer=new char[Size]; 
                //紧接着索引表的后面就是该表记录,表记录的个数由索引头的Count值确定 
                oeFile->Seek(iheader.FilePos + sizeof(iheader), soFromBeginning); 
                oeFile->Read(Buffer, Size);//读取所有的索引项 
                pIndexItem=(Toe5_IndexItem*)Buffer; 
                //逐个读取表记录 
                for (i=0;i<icount;i++){ 
                    if ((*pIndexItem).HeaderPos > 0){ 
                        if (folders) 
                            ReadFolderInfo((*pIndexItem).HeaderPos,flist); 
                        else 
                            ReadMessageInfo((*pIndexItem).HeaderPos,flist); 
                    } 
                    if ((*pIndexItem).ChildIndex > 0){ 
                        //有些pIndexItem记录包括子邮件记录表 
                        if (tmpList->IndexOf((void*)(*pIndexItem).ChildIndex)==-1) 
                            ReadIndex((*pIndexItem).ChildIndex,flist,folders); 
                    } 
                    pIndexItem++; 
                } 
                delete []Buffer; 
            } 
        } 
    } 
} 
 
//=================================================================================== 
AnsiString __fastcall Read_OE_Message(AnsiString FileName,int position) 
{ 
    Toe5_MsgItem oe5_MsgItem; 
    AnsiString msg; 
    if(position>0){ 
        oeFile=new TFileStream(GetOEDirectory()+"\\"+FileName,fmOpenRead|fmShareDenyNone); 
        GetFileInfo(); 
        msg=""; 
        if (finfo.IndexItemsCount > 0){ 
            oeFile->Seek(position, soFromBeginning); 
            while(1){ 
                oeFile->Read(&oe5_MsgItem, sizeof(Toe5_MsgItem)); 
                if (oe5_MsgItem.FilePos != position)break; 
                msg=msg + oe5_MsgItem.MsgContent; 
                position=oe5_MsgItem.NextItem; 
                if (position == 0)break; 
                oeFile->Seek(position, soFromBeginning); 
            } 
        } 
        delete oeFile; 
    } 
    return msg; 
} 
 
//=================================================================================== 
 
void __fastcall Read_OE_File(AnsiString FileName, TList* flist) 
{ 
    int position; 
 
    if (flist !=NULL){ 
        oeFile=new TFileStream(GetOEDirectory()+"\\"+FileName, fmOpenRead|fmShareDenyNone); 
        GetFileInfo(); 
        if (finfo.IndexItemsCount > 0){ 
            tmpList=new TList(); 
            //第一个索引表头结构位于0x30处 
            oeFile->Seek(0x30, soFromBeginning); 
            oeFile->Read(&position, sizeof(position)); 
            ReadIndex(position,flist,FileName=="folders.dbx"); 
            delete tmpList; 
        } 
        delete oeFile; 
    } 
} 
 
void __fastcall TForm1::Button1Click(TObject *Sender) 
{ 
    TList* flist=new TList(); 
    //读取邮件 
    Read_OE_File("收件箱.dbx",flist); 
    if(ClientDataSet1->Active)ClientDataSet1->Close(); 
    ClientDataSet1->CreateDataSet(); 
    Toe5_MessageInfo* oe5_MessageInfo; 
 
    for(int i=0;i<flist->Count;i++){ 
        ClientDataSet1->Append(); 
        oe5_MessageInfo=(Toe5_MessageInfo*)flist->Items[i]; 
        ClientDataSet1->FieldByName("Msg")->AsInteger=oe5_MessageInfo->Msg; 
        ClientDataSet1->FieldByName("MsgFlags")->AsInteger=oe5_MessageInfo->MsgFlags; 
        ClientDataSet1->FieldByName("AccountID")->AsString=oe5_MessageInfo->AccountID; 
        ClientDataSet1->FieldByName("Account")->AsString=oe5_MessageInfo->Account; 
        ClientDataSet1->FieldByName("MessageID")->AsString=oe5_MessageInfo->MessageID; 
        ClientDataSet1->FieldByName("Sent")->AsDateTime=FileTimeToDateTime(oe5_MessageInfo->Sent); 
        ClientDataSet1->FieldByName("Received")->AsDateTime=FileTimeToDateTime(oe5_MessageInfo->Received); 
        ClientDataSet1->FieldByName("Subject")->AsString=oe5_MessageInfo->Subject; 
        ClientDataSet1->FieldByName("From")->AsString=oe5_MessageInfo->From; 
        ClientDataSet1->FieldByName("From_Reply")->AsString=oe5_MessageInfo->From_Reply; 
        ClientDataSet1->FieldByName("Receipt")->AsString=oe5_MessageInfo->Receipt; 
        ClientDataSet1->FieldByName("Reply_To")->AsString=oe5_MessageInfo->Reply_To; 
        ClientDataSet1->FieldByName("References")->AsString=oe5_MessageInfo->References; 
        ClientDataSet1->FieldByName("NewsGroup")->AsString=oe5_MessageInfo->NewsGroup; 
        ClientDataSet1->FieldByName("Size")->AsInteger=oe5_MessageInfo->size; 
        ClientDataSet1->FieldByName("Position")->AsInteger=oe5_MessageInfo->position; 
        ClientDataSet1->FieldByName("HeaderPosition")->AsInteger=oe5_MessageInfo->HeaderPosition; 
        ClientDataSet1->Post(); 
        delete oe5_MessageInfo; 
    } 
    delete flist; 
} 
//--------------------------------------------------------------------------- 
 
void __fastcall TForm1::Button2Click(TObject *Sender) 
{ 
    Memo1->Lines->Text=Read_OE_Message("收件箱.dbx",ClientDataSet1->FieldByName("Position")->AsInteger); 
} 
//--------------------------------------------------------------------------- 
 
void __fastcall TForm1::Button3Click(TObject *Sender) 
{ 
    if(SaveDialog1->Execute()){ 
        Memo1->Lines->SaveToFile(SaveDialog1->FileName); 
    } 
} 
//--------------------------------------------------------------------------- 
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值