//--------------------------------------------------------------------------- #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); } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #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); } } //---------------------------------------------------------------------------