// -------------------------------------------------------------------------------- // Moletest.cpp // -------------------------------------------------------------------------------- #define DEFINE_STRCONST #define INITGUID #include #include #include #include #include #include #include #include #include "resource.h" #include IMimeOleMalloc *g_pMalloc=NULL; // -------------------------------------------------------------------------------- // Prototypes // -------------------------------------------------------------------------------- void MoleTestHeader(IStorage *pStorage); void MoleTestBody(IStorage *pStorage); INT_PTR CALLBACK MimeOLETest(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK RichStreamShow(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); // -------------------------------------------------------------------------------- // Simple (UNSAFE) conversion to UNICODE // -------------------------------------------------------------------------------- OLECHAR* ConvertToUnicode(char *szA) { static OLECHAR achW[1024]; MultiByteToWideChar(CP_ACP, 0, szA, -1, achW, 1024); return achW; } // -------------------------------------------------------------------------------- // Simple (UNSAFE) conversion to ANSI // -------------------------------------------------------------------------------- char* ConvertToAnsi(OLECHAR FAR* szW) { static char achA[1024]; WideCharToMultiByte(CP_ACP, 0, szW, -1, achA, 1024, NULL, NULL); return achA; } // -------------------------------------------------------------------------------- // Moletest entry point // -------------------------------------------------------------------------------- void main(int argc, char *argv[]) { // Locals CHAR szDocFile[MAX_PATH]; IStorage *pStorage=NULL; HRESULT hr; HINSTANCE hRichEdit=NULL; // Must have a path to a .stg file... if (argc != 2) { printf("Please enter the path and file name that mbxtodoc.exe generated: "); scanf("%s", szDocFile); fflush(stdin); } // Otherwise, copy parmaeter else lstrcpyn(szDocFile, argv[1], sizeof(szDocFile)); hRichEdit = LoadLibrary("RICHED32.DLL"); // Init OLE hr = CoInitialize(NULL); if (FAILED(hr)) { printf("Error - Unable to initialize OLE.\n"); exit(1); } // Get IMimeOleMalloc hr = CoCreateInstance(CLSID_MIMEOLE, NULL, CLSCTX_INPROC_SERVER, IID_IMimeOleMalloc, (LPVOID *)&g_pMalloc); if (FAILED(hr)) { printf("Error - CoCreateInstance of CLSID_MIMEOLE\\IID_IMimeOleMalloc failed.\n"); goto exit; } // Status printf("Opening source docfile: %s\n", szDocFile); // Get file /* hr = StgOpenStorage(ConvertToUnicode(szDocFile), NULL, STGM_TRANSACTED | STGM_NOSCRATCH | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &pStorage); if (FAILED(hr)) { printf("StgOpenStorage failed\n"); goto exit; } */ DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_TEST), NULL, MimeOLETest, (LPARAM)szDocFile); //MoleTestBody(pStorage); exit: // Cleanup if (hRichEdit) FreeLibrary(hRichEdit); if (pStorage) pStorage->Release(); if (g_pMalloc) g_pMalloc->Release(); // Un-init OLE CoUninitialize(); // Done return; } // -------------------------------------------------------------------------------- // This is the IMimeHeader torture test // -------------------------------------------------------------------------------- void MoleTestHeader(IStorage *pStorage) { // Locals IMimeHeader *pHeader=NULL; IEnumSTATSTG *pEnum=NULL; IStream *pStream=NULL; STATSTG rElement; ULONG i, c; HRESULT hr=S_OK; CHAR szData[50]; IStream *pSave=NULL, *pstmHeader=NULL; IMimeEnumHeaderLines *pEnumLines=NULL; LPSTR pszData; // Status printf("Starting IMimeHeader torture test...\n"); // Create a header object... hr = CoCreateInstance(CLSID_MIMEOLE, NULL, CLSCTX_INPROC_SERVER, IID_IMimeHeader, (LPVOID *)&pHeader); if (FAILED(hr)) { printf("Error - CoCreateInstance of CLSID_Mime\\IID_IMimeHeader failed.\n"); goto exit; } // Get storage enumerator hr = pStorage->EnumElements(0, NULL, 0, &pEnum); if (FAILED(hr)) { printf("Error - IStorage::EnumElements failed.\n"); goto exit; } // Enumerate for(i=0;;i++) { // Status //printf("Message: %d\n", i); // Get element hr = pEnum->Next(1, &rElement, &c); if (FAILED(hr)) break; if (c == 0) break; // No Name ? if (NULL == rElement.pwcsName) continue; // Open the stream... hr = pStorage->OpenStream(rElement.pwcsName, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &pStream); if (FAILED(hr)) { printf("IStorage::OpenStream failed: (iMsg = %d)\n", i); goto nextmsg; } // Load the header... hr = pHeader->Load(pStream); if (FAILED(hr)) { printf("IMimeHeader::Load failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } #if 0 // Test Enumerator hr = pHeader->EnumHeaderLines(NULL, &pEnumLines); if (FAILED(hr)) printf("IMimeHeader::EnumLines failed (HR = %08X): (iMsg = %d)\n", hr, i); else { ULONG cLines; //ULONG x; HEADERLINE rgLine[2]; while(SUCCEEDED(pEnumLines->Next(2, rgLine, &cLines)) && cLines) { //for (x=0; xFreeHeaderLineArray(cLines, rgLine, FALSE); } pEnumLines->Release(); pEnumLines = NULL; } // Test Enumerator hr = pHeader->EnumHeaderLines("Received", &pEnumLines); if (FAILED(hr)) printf("IMimeHeader::EnumLines failed (HR = %08X): (iMsg = %d)\n", hr, i); else { ULONG cLines; //ULONG x; HEADERLINE rgLine[2]; while(SUCCEEDED(pEnumLines->Next(2, rgLine, &cLines)) && cLines) { //for (x=0; xFreeHeaderLineArray(cLines, rgLine, FALSE); } pEnumLines->Release(); pEnumLines = NULL; } // Test IMimeHeader Interface pHeader->IsContentType(NULL, NULL); pHeader->IsContentType(STR_CNT_MESSAGE, NULL); pHeader->IsContentType(NULL, STR_SUB_PLAIN); // **************************************************************************************** // Get a few items... if (i == 0) pHeader->GetInetProp(NULL, NULL); pszData = NULL; hr = pHeader->GetInetProp("To", &pszData); if (FAILED(hr) && hr != MIME_E_NOT_FOUND) printf("IMimeHeader::GetInetProp(\"To\") failed (HR = %08X): (iMsg = %d)\n", hr, i); else if (pszData) g_pMalloc->Free(pszData); // Get a few items... pszData = NULL; hr = pHeader->GetInetProp("Subject", &pszData); if (FAILED(hr) && hr != MIME_E_NOT_FOUND) printf("IMimeHeader::GetInetProp(\"Subject\") failed (HR = %08X): (iMsg = %d)\n", hr, i); else if (pszData) g_pMalloc->Free(pszData); // Get a few items... (multi-line header) pszData = NULL; hr = pHeader->GetInetProp("Received", &pszData); if (FAILED(hr) && hr != MIME_E_NOT_FOUND) printf("IMimeHeader::GetInetProp(\"Received\") failed (HR = %08X): (iMsg = %d)\n", hr, i); else if (pszData) g_pMalloc->Free(pszData); // Get a few items... (multi-line header) pszData = NULL; hr = pHeader->GetInetProp("Content-Type", &pszData); if (FAILED(hr) && hr != MIME_E_NOT_FOUND) printf("IMimeHeader::GetInetProp(\"Content-Type\") failed (HR = %08X): (iMsg = %d)\n", hr, i); else if (pszData) g_pMalloc->Free(pszData); // **************************************************************************************** // Prepare a line to set in a bunch of items... wsprintf(szData, "", ConvertToAnsi(rElement.pwcsName)); // Set a few items... if (i == 0) pHeader->SetInetProp(NULL, NULL); hr = pHeader->SetInetProp("To", szData); if (FAILED(hr)) printf("IMimeHeader::SetInetProp(\"To\") failed (HR = %08X): (iMsg = %d)\n", hr, i); // Get a few items... hr = pHeader->SetInetProp("Subject", szData); if (FAILED(hr)) printf("IMimeHeader::SetInetProp(\"Subject\") failed (HR = %08X): (iMsg = %d)\n", hr, i); // Get a few items... (multi-line header) hr = pHeader->SetInetProp("Received", szData); if (FAILED(hr)) printf("IMimeHeader::SetInetProp(\"Received\") failed (HR = %08X): (iMsg = %d)\n", hr, i); // Get a few items... (multi-line header) hr = pHeader->SetInetProp("Content-Type", "multipart\\related"); if (FAILED(hr)) printf("IMimeHeader::SetInetProp(\"Content-Type\") failed (HR = %08X): (iMsg = %d)\n", hr, i); // **************************************************************************************** // Delete a few items if (i == 0) pHeader->DelInetProp(NULL); hr = pHeader->DelInetProp("MIME-Version"); if (FAILED(hr) && hr != MIME_E_NOT_FOUND) printf("IMimeHeader::DelInetProp(\"MIME-Version\") failed (HR = %08X): (iMsg = %d)\n", hr, i); // Delete a few items hr = pHeader->DelInetProp("Content-Disposition"); if (FAILED(hr) && hr != MIME_E_NOT_FOUND) printf("IMimeHeader::DelInetProp(\"Content-Disposition\") failed (HR = %08X): (iMsg = %d)\n", hr, i); // **************************************************************************************** // Get some parameters if (i == 0) { pHeader->SetInetProp(NULL, NULL); pHeader->GetInetProp("Content-Type", NULL); pHeader->GetInetProp("par:content-type:name", NULL); } pszData = NULL; pHeader->GetInetProp("par:content-type:name", &pszData); if (FAILED(hr) && hr != MIME_E_NOT_FOUND && hr != MIME_E_NO_DATA) printf("IMimeHeader::GetInetProp(...,\"name\") failed (HR = %08X): (iMsg = %d)\n", hr, i); else if (pszData) g_pMalloc->Free(pszData); pszData = NULL; hr = pHeader->GetInetProp("par:Content-Disposition:filename", &pszData); if (FAILED(hr) && hr != MIME_E_NOT_FOUND && hr != MIME_E_NO_DATA) printf("IMimeHeader::GetInetProp(...,\"filename\") failed (HR = %08X): (iMsg = %d)\n", hr, i); else if (pszData) g_pMalloc->Free(pszData); pszData = NULL; hr = pHeader->GetInetProp("par:Content-Type:charset", &pszData); if (FAILED(hr) && hr != MIME_E_NOT_FOUND && hr != MIME_E_NO_DATA) printf("IMimeHeader::GetInetProp(...,\"charset\") failed (HR = %08X): (iMsg = %d)\n", hr, i); else if (pszData) g_pMalloc->Free(pszData); pszData = NULL; hr = pHeader->GetInetProp("par:Content-Type:boundary", &pszData); if (FAILED(hr) && hr != MIME_E_NOT_FOUND && hr != MIME_E_NO_DATA) printf("IMimeHeader::GetInetProp(...,\"boundary\") failed (HR = %08X): (iMsg = %d)\n", hr, i); else if (pszData) g_pMalloc->Free(pszData); pszData = NULL; hr = pHeader->GetInetProp("par:Content-Type:part", &pszData); if (FAILED(hr) && hr != MIME_E_NOT_FOUND && hr != MIME_E_NO_DATA) printf("IMimeHeader::GetInetProp(...,\"part\") failed (HR = %08X): (iMsg = %d)\n", hr, i); else if (pszData) g_pMalloc->Free(pszData); // **************************************************************************************** // Set some parameters if (i == 0) { pHeader->SetInetProp(NULL, NULL); pHeader->SetInetProp("Content-Type", NULL); pHeader->SetInetProp("par:Content-Type:name", NULL); } hr = pHeader->SetInetProp("par:Content-Type:name", szData); if (FAILED(hr)) printf("IMimeHeader::SetInetProp(...,\"name\") failed (HR = %08X): (iMsg = %d)\n", hr, i); hr = pHeader->SetInetProp("par:Content-Disposition:filename", szData); if (FAILED(hr)) printf("IMimeHeader::SetInetProp(...,\"filename\") failed (HR = %08X): (iMsg = %d)\n", hr, i); hr = pHeader->SetInetProp("par:Content-Type:charset", szData); if (FAILED(hr)) printf("IMimeHeader::SetInetProp(...,\"charset\") failed (HR = %08X): (iMsg = %d)\n", hr, i); hr = pHeader->SetInetProp("par:content-type:boundary", szData); if (FAILED(hr)) printf("IMimeHeader::SetInetProp(...,\"boundary\") failed (HR = %08X): (iMsg = %d)\n", hr, i); hr = pHeader->SetInetProp("par:content-type:part", szData); if (FAILED(hr)) printf("IMimeHeader::SetInetProp(...,\"boundary\") failed (HR = %08X): (iMsg = %d)\n", hr, i); hr = pHeader->DelInetProp("par:content-type:part"); if (FAILED(hr)) printf("IMimeHeader::DelInetProp(...,\"boundary\") failed (HR = %08X): (iMsg = %d)\n", hr, i); // **************************************************************************************** // Try to save it back if (i == 0) pHeader->GetSizeMax(NULL); //hr = pHeader->GetSizeMax(&uli); //if (FAILED(hr)) // printf("IMimeHeader::GetSizeMax() failed (HR = %08X): (iMsg = %d)\n", hr, i); hr = pHeader->IsDirty(); if (FAILED(hr)) printf("IMimeHeader::IsDirty() failed (HR = %08X): (iMsg = %d)\n", hr, i); CreateStreamOnHGlobal(NULL, TRUE, &pstmHeader); hr = pHeader->Save(pstmHeader, TRUE); if (FAILED(hr)) printf("IMimeHeader::Save() failed (HR = %08X): (iMsg = %d)\n", hr, i); pstmHeader->Release(); #endif nextmsg: // Cleanup pStream->Release(); pStream = NULL; // Free the name CoTaskMemFree(rElement.pwcsName); } exit: // Cleanup if (pEnum) pEnum->Release(); if (pHeader) pHeader->Release(); if (pStream) pStream->Release(); if (pEnumLines) pEnumLines->Release(); // Done return; } // -------------------------------------------------------------------------------- // This is the IMimeBody torture test // -------------------------------------------------------------------------------- void MoleTestBody(IStorage *pStorage) { // Locals IMimeMessage *pMessage=NULL; IEnumSTATSTG *pEnum=NULL; IStream *pStream=NULL, *pstmTree=NULL; STATSTG rElement; ULONG i, c, cbRead, x; HRESULT hr=S_OK; LARGE_INTEGER liOrigin = {0,0}; HBODY hBody; IMimeBody *pBody=NULL; IStream *pBodyStream=NULL; BYTE rgbBuffer[1024]; FINDBODY rFindBody; FILETIME ft; IMimeMessageParts *pParts=NULL; IStream *pSave=NULL; IDataObject *pDataObject=NULL; IMimeAddressTable *pAddressTable=NULL; LPSTR pszData=NULL; IMimeMessage *pCombine=NULL; IMimeBody *pRootBody=NULL; // Status printf("Starting IMimeBody torture test...\n"); // Create a header object... hr = CoCreateInstance(CLSID_MIMEOLE, NULL, CLSCTX_INPROC_SERVER, IID_IMimeMessage, (LPVOID *)&pMessage); if (FAILED(hr)) { printf("Error - CoCreateInstance of CLSID_Mime\\IID_IMimeBody failed.\n"); goto exit; } // Get storage enumerator hr = pStorage->EnumElements(0, NULL, 0, &pEnum); if (FAILED(hr)) { printf("Error - IStorage::EnumElements failed.\n"); goto exit; } // Enumerate for(i=0;;i++) { // Status // printf("Message: %d\n", i); // Get element hr = pEnum->Next(1, &rElement, &c); if (FAILED(hr)) break; if (c == 0) break; // No Name ? if (NULL == rElement.pwcsName) continue; // Open the stream... hr = pStorage->OpenStream(rElement.pwcsName, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &pStream); if (FAILED(hr)) { printf("IStorage::OpenStream failed: (iMsg = %d)\n", i); goto nextmsg; } // Init New the message hr = pMessage->InitNew(); if (FAILED(hr)) { printf("pMessage->InitNew failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } // Load the header... hr = pMessage->BindToMessage(pStream); if (FAILED(hr)) { printf("pMessage->BindMessage failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } #if 0 hr = pMessage->SplitMessage(64 * 1024, &pParts); if (FAILED(hr)) MessageBox(NULL, "IMimeMessage::SplitMessage failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); else { hr = pParts->CombineParts(&pCombine); if (FAILED(hr)) MessageBox(NULL, "IMimeMessageParts::CombineParts failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); else pCombine->Release(); pParts->Release(); } // Test Addresss List hr = pMessage->GetAddressList(&pAddressTable); if (FAILED(hr)) printf("IMimeHeader::GetAddressList failed (HR = %08X): (iMsg = %d)\n", hr, i); else { IADDRESSLIST rList; /* hr = pAddressTable->GetViewable(IAT_TO, TRUE, &pszData); if (FAILED(hr)) printf("IMimeAddressList::GetViewable failed (HR = %08X): (iMsg = %d)\n", hr, i); else g_pMalloc->Free(pszData); */ hr = pAddressTable->GetList(IAT_ALL, &rList); if (FAILED(hr) && hr != MIME_E_NO_DATA) printf("IMimeAddressList::GetList failed (HR = %08X): (iMsg = %d)\n", hr, i); else if (SUCCEEDED(hr)) { // for (x=0; xFreeAddressList(&rList); // printf("------------------------------------------------------------------------\n"); } pAddressTable->Release(); } // QI for body tree hr = pMessage->BindToObject(HBODY_ROOT, IID_IMimeBody, (LPVOID *)&pRootBody); if (FAILED(hr)) { printf("pMessage->GetRootBody failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } hr = pRootBody->SetInetProp(STR_HDR_CNTTYPE, "text/plain"); if (FAILED(hr)) MessageBox(NULL, "pRootBody->SetInetProp failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); // Get the time... hr = pRootBody->GetSentTime(&ft); if (FAILED(hr)) MessageBox(NULL, "IMimeMessage::GetSentTime failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); hr = pRootBody->SetSentTime(&ft); if (FAILED(hr)) MessageBox(NULL, "IMimeMessage::SetSentTime failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); hr =pRootBody->GetReceiveTime(&ft); if (FAILED(hr)) MessageBox(NULL, "IMimeMessage::GetReceiveTime failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); hr = pMessage->GetTextBody(NULL, NULL, &pSave); if (FAILED(hr) && hr != MIME_E_NO_DATA) MessageBox(NULL, "IMimeMessage::GetTextBody failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); else if (pSave) pSave->Release(); hr = pMessage->GetTextBody("html", NULL, &pSave); if (FAILED(hr) && hr != MIME_E_NO_DATA) MessageBox(NULL, "IMimeMessage::GetTextBody failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); else if (pSave) pSave->Release(); CreateStreamOnHGlobal(NULL, TRUE, &pSave); hr = pMessage->SaveMessage(pSave, TRUE); if (FAILED(hr)) MessageBox(NULL, "IMimeMessage::GetReceiveTime failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); pSave->Release(); hr = pMessage->QueryInterface(IID_IDataObject, (LPVOID *)&pDataObject); if (FAILED(hr)) MessageBox(NULL, "IMimeMessage::QueryInterface failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); else { OleSetClipboard(pDataObject); pDataObject->Release(); } // Get Message Source pStream->Release(); pStream = NULL; hr = pMessage->GetMessageSource(&pStream); if (FAILED(hr)) { printf("IMimeMessageTree::GetMessageSource failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } // Create body tree stream hr = CreateStreamOnHGlobal(NULL, TRUE, &pstmTree); if (FAILED(hr)) { printf("CreateStreamOnHGlobal failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } // find first/next loop ZeroMemory(&rFindBody, sizeof(rFindBody)); rFindBody.pszCntType = (LPSTR)STR_CNT_TEXT; hr = pMessage->FindFirst(&rFindBody, &hBody); if (FAILED(hr) && hr != MIME_E_NOT_FOUND) { printf("pMessage->FindFirst failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } else if (SUCCEEDED(hr)) { while(1) { // Open the body hr = pMessage->BindToObject(hBody, IID_IMimeBody, (LPVOID *)&pBody); if (FAILED(hr)) { printf("pMessage->BindToObject failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } // Get the body stream... if (SUCCEEDED(pBody->GetData(FMT_BINARY, &pBodyStream))) { // Seek to end and then begginnging hr = pBodyStream->Seek(liOrigin, STREAM_SEEK_END, NULL); if (FAILED(hr)) { printf("pBodyStream->Seek failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } // Seek to end and then begginnging hr = pBodyStream->Seek(liOrigin, STREAM_SEEK_SET, NULL); if (FAILED(hr)) { printf("pBodyStream->Seek failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } // Lets read data from the stream while(1) { // Read block hr = pBodyStream->Read(rgbBuffer, sizeof(rgbBuffer) - 1, &cbRead); if (FAILED(hr)) { printf("pBodyStream->Read failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } // Done if (0 == cbRead) break; // rgbBuffer[cbRead] = '\0'; // printf("%s", (LPSTR)rgbBuffer); } pBodyStream->Release(); pBodyStream = NULL; // printf("\n======================================================================\n"); // _getch(); } // Release pBody->Release(); pBody = NULL; // Get Next if (FAILED(pMessage->FindNext(&rFindBody, &hBody))) break; } } // Save the Tree hr = pMessage->SaveTree(pstmTree); if (FAILED(hr)) { printf("pMessage->Save failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } // Commit the stream hr = pstmTree->Commit(STGC_DEFAULT); if (FAILED(hr)) { printf("pstmTree->Commit failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } // Rewind it hr = pstmTree->Seek(liOrigin, STREAM_SEEK_SET, NULL); if (FAILED(hr)) { printf("pstmTree->Seek failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } // Init the tree hr = pMessage->InitNew(); if (FAILED(hr)) { printf("pMessage->InitNew failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } // Load the body tree hr = pMessage->LoadTree(pstmTree); if (FAILED(hr)) { printf("pMessage->Load failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } // Rewind message stream hr = pStream->Seek(liOrigin, STREAM_SEEK_SET, NULL); if (FAILED(hr)) { printf("pStream->Seek failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } // Rebind hr = pMessage->BindMessage(pStream); if (FAILED(hr)) { printf("pMessage->BindMessage failed (HR = %08X): (iMsg = %d)\n", hr, i); goto nextmsg; } #endif nextmsg: // Cleanup if (pstmTree) { pstmTree->Release(); pstmTree = NULL; } if (pRootBody) { pRootBody->Release(); pRootBody = NULL; } if (pStream) { pStream->Release(); pStream = NULL; } if (pBody) { pBody->Release(); pBody = NULL; } if (pBodyStream) { pBodyStream->Release(); pBodyStream=NULL; } // Free the name CoTaskMemFree(rElement.pwcsName); } exit: // Cleanup if (pEnum) pEnum->Release(); if (pMessage) pMessage->Release(); if (pstmTree) pstmTree->Release(); if (pStream) pStream->Release(); // Done return; } void TreeViewInsertBody(HWND hwnd, IMimeMessageTree *pTree, HBODY hBody, HTREEITEM hParent, HTREEITEM hInsertAfter, HTREEITEM *phItem) { // Locals IMimeHeader *pHeader=NULL; LPSTR pszCntType=NULL, pszEncType=NULL, pszFree=NULL, psz=NULL, pszFileName=NULL, pszFName; TV_INSERTSTRUCT tvi; HRESULT hr; HTREEITEM hCurrent, hNew; HBODY hChild; // Get Header hr = pTree->BindToObject(hBody, IID_IMimeHeader, (LPVOID *)&pHeader); if (FAILED(hr)) { MessageBox(GetParent(hwnd), "IMimeMessageTree->BindToObject - IID_IMimeHeader failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); goto exit; } // Get content type hr = pHeader->GetInetProp(STR_HDR_CNTTYPE, &pszCntType); if (FAILED(hr)) { MessageBox(GetParent(hwnd), "IMimeHeader->GetContentType failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); goto exit; } // Get content type if (FAILED(pHeader->GetInetProp(STR_HDR_CNTENC, &pszFree))) pszEncType = (LPSTR)"Unknown"; else pszEncType = pszFree; // Get content type if (FAILED(pHeader->GetInetProp(STR_ATT_FILENAME, &pszFileName))) pszFName = (LPSTR)"Unknown"; else pszFName = pszFileName; // Build content-type string psz = (LPSTR)CoTaskMemAlloc(lstrlen(pszCntType) + lstrlen(pszEncType) + lstrlen(pszFName) + 15); // Insert ZeroMemory(&tvi, sizeof(TV_INSERTSTRUCT)); tvi.hParent = hParent; tvi.hInsertAfter = hInsertAfter; tvi.item.mask = TVIF_PARAM | TVIF_TEXT; tvi.item.lParam = (LPARAM)hBody; tvi.item.cchTextMax = wsprintf(psz, "%s - %s (%s)", pszCntType, pszEncType, pszFName); tvi.item.pszText = psz; // Insert it *phItem = hCurrent = TreeView_InsertItem(hwnd, &tvi); // Multipart... if (pHeader->IsContentType(STR_CNT_MULTIPART, NULL) == S_OK) { // Get first child... hr = pTree->GetBody(BODY_FIRST_CHILD, hBody, &hChild); if (FAILED(hr)) { MessageBox(GetParent(hwnd), "IMimeMessageTree->GetBody - BODY_FIRST_CHILD failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); goto exit; } // Loop while(hChild) { // Insert it TreeViewInsertBody(hwnd, pTree, hChild, hCurrent, TVI_LAST, &hNew); // Next hr = pTree->GetBody(BODY_NEXT, hChild, &hChild); if (FAILED(hr)) break; } } TreeView_Expand(hwnd, *phItem, TVE_EXPAND); exit: // Cleanup if (pHeader) pHeader->Release(); if (pszCntType) g_pMalloc->Free(pszCntType); if (pszFileName) g_pMalloc->Free(pszFileName); if (pszFree) g_pMalloc->Free(pszFree); if (psz) CoTaskMemFree(psz); // Done return; } void TreeViewMessage(HWND hwnd, IMimeMessage *pMessage) { // Locals IMimeMessageTree *pTree=NULL; HBODY hBody; HRESULT hr=S_OK; HTREEITEM hRoot; // Delete All TreeView_DeleteAllItems(hwnd); // QI for body tree hr = pMessage->QueryInterface(IID_IMimeMessageTree, (LPVOID *)&pTree); if (FAILED(hr)) { MessageBox(GetParent(hwnd), "IMimeMessage->QueryInterface - IID_IMimeMessageTree failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); goto exit; } // Get the root body object hr = pTree->GetBody(BODY_ROOT, NULL, &hBody); if (FAILED(hr)) { MessageBox(GetParent(hwnd), "IMimeMessageTree->GetBody - BODY_ROOT failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); goto exit; } // Insert Body TreeViewInsertBody(hwnd, pTree, hBody, TVI_ROOT, TVI_FIRST, &hRoot); // Expand all TreeView_SelectItem(GetDlgItem(hwnd, IDC_LIST), hRoot); exit: // Cleanup if (pTree) pTree->Release(); // Done return; } DWORD CALLBACK EditStreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG FAR *pcb) { LPSTREAM pstm=(LPSTREAM)dwCookie; if(pstm) pstm->Read(pbBuff, cb, (ULONG *)pcb); return NOERROR; } HRESULT HrRicheditStreamIn(HWND hwndRE, LPSTREAM pstm, ULONG uSelFlags) { EDITSTREAM es; if(!pstm) return E_INVALIDARG; if(!IsWindow(hwndRE)) return E_INVALIDARG; es.dwCookie = (DWORD)pstm; es.pfnCallback=(EDITSTREAMCALLBACK)EditStreamInCallback; SendMessage(hwndRE, EM_STREAMIN, uSelFlags, (LONG)&es); return NOERROR; } BOOL FOpenStorage(HWND hwnd, LPSTR pszFile, IStorage **ppStorage, IEnumSTATSTG **ppEnum) { // Locals HRESULT hr; // Get file hr = StgOpenStorage(ConvertToUnicode(pszFile), NULL, STGM_TRANSACTED | STGM_NOSCRATCH | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, ppStorage); if (FAILED(hr)) { MessageBox(hwnd, "StgOpenStorage failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); return FALSE; } // Get First element hr = (*ppStorage)->EnumElements(0, NULL, 0, ppEnum); if (FAILED(hr)) { MessageBox(hwnd, "IStorage::EnumElements failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); return FALSE; } // Done return TRUE; } BOOL FOpenMessage(HWND hwnd, IMimeMessage *pMessage, IStorage *pStorage) { HRESULT hr; BOOL fResult=FALSE; LARGE_INTEGER liOrigin = {0,0}; CHAR szName[255]; LPSTREAM pStream=NULL; LV_ITEM lvi; LPHBODY prgAttach=NULL; ULONG cAttach; // Get selected string ULONG i = ListView_GetNextItem(GetDlgItem(hwnd, IDC_LIST), -1, LVNI_SELECTED); if (-1 == i) return FALSE; // Get the name ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_TEXT; lvi.iItem = i; lvi.pszText = szName; lvi.cchTextMax = sizeof(szName); ListView_GetItem(GetDlgItem(hwnd, IDC_LIST), &lvi); // OpenStream hr = pStorage->OpenStream(ConvertToUnicode(szName), NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, 0, &pStream); if (FAILED(hr)) { MessageBox(hwnd, "IStorage::OpenStream failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); goto exit; } // Show Source pStream->Seek(liOrigin, STREAM_SEEK_SET, NULL); HrRicheditStreamIn(GetDlgItem(hwnd, IDE_EDIT), pStream, SF_TEXT); // Load the message pStream->Seek(liOrigin, STREAM_SEEK_SET, NULL); pMessage->InitNew(); hr = pMessage->BindToMessage(pStream); if (FAILED(hr)) { MessageBox(hwnd, "IMimeMessage::Load failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); goto exit; } // Save it back out #if 0 pMessage->SetInetProp(HBODY_ROOT, STR_HDR_SUBJECT, "This is a test..."); pMessage->GetAttached(&cAttach, &prgAttach); for (i=0; iDeleteBody(prgAttach[i]); if (prgAttach) g_pMalloc->Free(prgAttach); pMessage->Commit(); #endif // View the message TreeViewMessage(GetDlgItem(hwnd, IDC_TREE), pMessage); // Success fResult = TRUE; exit: // Cleanup if (pStream) pStream->Release(); // Done return TRUE; } // -------------------------------------------------------------------------------- // MimeOLETest // -------------------------------------------------------------------------------- INT_PTR CALLBACK MimeOLETest(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { // Locals static CHAR s_szFile[MAX_PATH]; static IMimeMessage *s_pMessage=NULL; static IStorage *s_pStorage=NULL; IMimeBody *pBody; IStream *pStream; HRESULT hr; IEnumSTATSTG *pEnum=NULL; TV_ITEM tvi; ULONG c; STATSTG rElement; HTREEITEM hItem; LV_COLUMN lvm; LV_ITEM lvi; HWND hwndC; // Handle the message switch(uMsg) { // Initialize case WM_INITDIALOG: // Create a header object... hr = CoCreateInstance(CLSID_MIMEOLE, NULL, CLSCTX_INPROC_SERVER, IID_IMimeMessage, (LPVOID *)&s_pMessage); if (FAILED(hr)) { MessageBox(hwnd, "CoCreateInstance - IID_IMimeMessage failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); return FALSE; } //s_pMessage->TestMe(); // Formats hwndC = GetDlgItem(hwnd, IDCB_FORMAT); c = SendMessage(hwndC, CB_ADDSTRING, 0, (LPARAM)"FMT_BINARY"); SendMessage(hwndC, CB_SETITEMDATA, c, FMT_BINARY); c = SendMessage(hwndC, CB_ADDSTRING, 0, (LPARAM)"FMT_INETCSET"); SendMessage(hwndC, CB_SETITEMDATA, c, FMT_INETCSET); c = SendMessage(hwndC, CB_ADDSTRING, 0, (LPARAM)"FMT_XMIT64"); SendMessage(hwndC, CB_SETITEMDATA, c, FMT_XMIT64); c = SendMessage(hwndC, CB_ADDSTRING, 0, (LPARAM)"FMT_XMITUU"); SendMessage(hwndC, CB_SETITEMDATA, c, FMT_XMITUU); c = SendMessage(hwndC, CB_ADDSTRING, 0, (LPARAM)"FMT_XMITQP"); SendMessage(hwndC, CB_SETITEMDATA, c, FMT_XMITQP); c = SendMessage(hwndC, CB_ADDSTRING, 0, (LPARAM)"FMT_XMIT7BIT"); SendMessage(hwndC, CB_SETITEMDATA, c, FMT_XMIT7BIT); c = SendMessage(hwndC, CB_ADDSTRING, 0, (LPARAM)"FMT_XMIT8BIT"); SendMessage(hwndC, CB_SETITEMDATA, c, FMT_XMIT8BIT); SendMessage(hwndC, CB_SETCURSEL, 0, 0); // To // ListView_SetExtendedListViewStyle(GetDlgItem(hwnd, IDC_LIST), LVS_EX_FULLROWSELECT); ZeroMemory(&lvm, sizeof(LV_COLUMN)); lvm.mask = LVCF_WIDTH | LVCF_TEXT; lvm.pszText = "MessageID"; lvm.cchTextMax = lstrlen(lvm.pszText); lvm.cx = 200; ListView_InsertColumn(GetDlgItem(hwnd, IDC_LIST), 0, &lvm); if (lParam) { // Copy File Name lstrcpyn(s_szFile, (LPSTR)lParam, MAX_PATH); // Set file name SetDlgItemText(hwnd, IDE_STORAGE, s_szFile); // Get file hr = StgOpenStorage(ConvertToUnicode(s_szFile), NULL, STGM_TRANSACTED | STGM_NOSCRATCH | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &s_pStorage); if (FAILED(hr)) { MessageBox(hwnd, "StgOpenStorage failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); return FALSE; } #if 0 //MoleTestHeader(s_pStorage); MoleTestBody(s_pStorage); s_pMessage->Release(); s_pStorage->Release(); exit(1); #endif // Get First element hr = s_pStorage->EnumElements(0, NULL, 0, &pEnum); if (FAILED(hr)) { MessageBox(hwnd, "IStorage::EnumElements failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); return FALSE; } // Enumerate ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_TEXT; lvi.iItem = 0; while(SUCCEEDED(pEnum->Next(1, &rElement, &c)) && c) { lvi.pszText = ConvertToAnsi(rElement.pwcsName); lvi.cchTextMax = lstrlen(lvi.pszText); ListView_InsertItem(GetDlgItem(hwnd, IDC_LIST), &lvi); CoTaskMemFree(rElement.pwcsName); lvi.iItem++; } // Select first item ListView_SetItemState(GetDlgItem(hwnd, IDC_LIST), 0, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED); // Release enum pEnum->Release(); } // Done return FALSE; case WM_NOTIFY: switch(wParam) { case IDC_LIST: { NM_LISTVIEW *pnmv; pnmv = (NM_LISTVIEW *)lParam; if (pnmv->uChanged & LVIF_STATE) { if (pnmv->uNewState & LVIS_SELECTED && pnmv->uNewState & LVIS_FOCUSED) FOpenMessage(hwnd, s_pMessage, s_pStorage); } } return 1; } break; // Handle Command case WM_COMMAND: switch(GET_WM_COMMAND_ID(wParam,lParam)) { case IDB_OPEN: hItem = TreeView_GetSelection(GetDlgItem(hwnd, IDC_TREE)); if (hItem) { ZeroMemory(&tvi, sizeof(TV_ITEM)); tvi.mask = TVIF_PARAM | TVIF_HANDLE; tvi.hItem = hItem; if (TreeView_GetItem(GetDlgItem(hwnd, IDC_TREE), &tvi)) { hr = s_pMessage->BindToObject((HBODY)tvi.lParam, IID_IMimeBody, (LPVOID *)&pBody); if (FAILED(hr)) { MessageBox(hwnd, "IMimeMessageTree::BindToObject failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); return FALSE; } c = SendMessage(GetDlgItem(hwnd, IDCB_FORMAT), CB_GETCURSEL, 0, 0); if (CB_ERR == c) { pBody->Release(); MessageBox(hwnd, "Select an Object Object Format", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); return FALSE; } hr = pBody->GetData((BODYFORMAT)SendMessage(GetDlgItem(hwnd, IDCB_FORMAT), CB_GETITEMDATA, c, 0), &pStream); if (FAILED(hr)) { pBody->Release(); MessageBox(hwnd, "IMimeMessageTree::BindToObject failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION); return FALSE; } DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_MESSAGE), NULL, RichStreamShow, (LPARAM)pStream); pBody->Release(); pStream->Release(); } } return 1; case IDCANCEL: EndDialog(hwnd, IDCANCEL); return 1; } break; // Close case WM_CLOSE: EndDialog(hwnd, IDB_NEXT); break; // Cleanup case WM_DESTROY: if (s_pMessage) s_pMessage->Release(); if (s_pStorage) s_pStorage->Release(); break; } return FALSE; } // -------------------------------------------------------------------------------- // RichStreamShow // -------------------------------------------------------------------------------- INT_PTR CALLBACK RichStreamShow(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_INITDIALOG: HrRicheditStreamIn(GetDlgItem(hwnd, IDE_EDIT), (IStream *)lParam, SF_TEXT); return FALSE; case WM_CLOSE: EndDialog(hwnd, IDCANCEL); break; } return FALSE; }