BOOL CImage::Load(CString sFileName) { Destroy(); FILE* f = NULL; _TFOPEN_S(f, sFileName.GetBuffer(0), _T("rb")); if(f==NULL) return FALSE; if(IsBitmap(f)) { fclose(f); return LoadBitmapFromBMPFile(sFileName.GetBuffer(0)); } else if(IsPNG(f)) { fclose(f); return LoadBitmapFromPNGFile(sFileName.GetBuffer(0)); } else if(IsJPEG(f)) { fclose(f); return LoadBitmapFromJPEGFile(sFileName.GetBuffer(0)); } fclose(f); return FALSE; }
// This method sends the report over SMTP BOOL CErrorReportSender::SendOverSMTP() { strconv_t strconv; if(g_CrashInfo.m_uPriorities[CR_SMTP]<0) { m_Assync.SetProgress(_T("Sending error report over SMTP is disabled (negative priority); skipping."), 0); return FALSE; } if(g_CrashInfo.m_sEmailTo.IsEmpty()) { m_Assync.SetProgress(_T("No E-mail address is specified for sending error report over SMTP; skipping."), 0); return FALSE; } m_EmailMsg.m_sFrom = (!g_CrashInfo.m_sEmailFrom.IsEmpty())?g_CrashInfo.m_sEmailFrom:g_CrashInfo.m_sEmailTo; m_EmailMsg.m_sTo = g_CrashInfo.m_sEmailTo; m_EmailMsg.m_nRecipientPort = g_CrashInfo.m_nSmtpPort; m_EmailMsg.m_sSubject = g_CrashInfo.m_sEmailSubject; if(g_CrashInfo.m_sEmailText.IsEmpty()) m_EmailMsg.m_sText = FormatEmailText(); else m_EmailMsg.m_sText = g_CrashInfo.m_sEmailText; m_EmailMsg.m_aAttachments.insert(m_sZipName); // Create and attach MD5 hash file CString sErrorRptHash; CalcFileMD5Hash(m_sZipName, sErrorRptHash); CString sFileTitle = m_sZipName; sFileTitle.Replace('/', '\\'); int pos = sFileTitle.ReverseFind('\\'); if(pos>=0) sFileTitle = sFileTitle.Mid(pos+1); sFileTitle += _T(".md5"); CString sTempDir; Utility::getTempDirectory(sTempDir); CString sTmpFileName = sTempDir +_T("\\")+ sFileTitle; FILE* f = NULL; _TFOPEN_S(f, sTmpFileName, _T("wt")); if(f!=NULL) { LPCSTR szErrorRptHash = strconv.t2a(sErrorRptHash.GetBuffer(0)); fwrite(szErrorRptHash, strlen(szErrorRptHash), 1, f); fclose(f); m_EmailMsg.m_aAttachments.insert(sTmpFileName); } int res = m_SmtpClient.SendEmailAssync(&m_EmailMsg, &m_Assync); return (res==0); }
BOOL CImage::IsImageFile(CString sFileName) { FILE* f = NULL; _TFOPEN_S(f, sFileName.GetBuffer(0), _T("rb")); if(f==NULL) return FALSE; if(IsBitmap(f) || IsPNG(f) || IsJPEG(f)) { fclose(f); return TRUE; } fclose(f); return FALSE; }
// This method sends the report over Simple MAPI BOOL CErrorReportSender::SendOverSMAPI() { strconv_t strconv; if(g_CrashInfo.m_uPriorities[CR_SMAPI]<0) { m_Assync.SetProgress(_T("Sending error report over SMAPI is disabled (negative priority); skipping."), 0); return FALSE; } if(g_CrashInfo.m_sEmailTo.IsEmpty()) { m_Assync.SetProgress(_T("No E-mail address is specified for sending error report over Simple MAPI; skipping."), 0); return FALSE; } if(g_CrashInfo.m_bSilentMode) { m_Assync.SetProgress(_T("Simple MAPI may require user interaction (not acceptable for non-GUI mode); skipping."), 0); return FALSE; } m_Assync.SetProgress(_T("Sending error report using Simple MAPI"), 0, false); m_Assync.SetProgress(_T("Initializing MAPI"), 1); BOOL bMAPIInit = m_MapiSender.MAPIInitialize(); if(!bMAPIInit) { m_Assync.SetProgress(m_MapiSender.GetLastErrorMsg(), 100, false); return FALSE; } if(m_SendAttempt!=0) { m_Assync.SetProgress(_T("[confirm_launch_email_client]"), 0); int confirm = 1; m_Assync.WaitForFeedback(confirm); if(confirm!=0) { m_Assync.SetProgress(_T("Cancelled by user"), 100, false); return FALSE; } } CString msg; CString sMailClientName; m_MapiSender.DetectMailClient(sMailClientName); msg.Format(_T("Launching the default email client (%s)"), sMailClientName); m_Assync.SetProgress(msg, 10); m_MapiSender.SetFrom(g_CrashInfo.m_sEmailFrom); m_MapiSender.SetTo(g_CrashInfo.m_sEmailTo); m_MapiSender.SetSubject(g_CrashInfo.m_sEmailSubject); CString sFileTitle = m_sZipName; sFileTitle.Replace('/', '\\'); int pos = sFileTitle.ReverseFind('\\'); if(pos>=0) sFileTitle = sFileTitle.Mid(pos+1); if(g_CrashInfo.m_sEmailText.IsEmpty()) m_MapiSender.SetMessage(FormatEmailText()); else m_MapiSender.SetMessage(g_CrashInfo.m_sEmailText); m_MapiSender.AddAttachment(m_sZipName, sFileTitle); // Create and attach MD5 hash file CString sErrorRptHash; CalcFileMD5Hash(m_sZipName, sErrorRptHash); sFileTitle += _T(".md5"); CString sTempDir; Utility::getTempDirectory(sTempDir); CString sTmpFileName = sTempDir +_T("\\")+ sFileTitle; FILE* f = NULL; _TFOPEN_S(f, sTmpFileName, _T("wt")); if(f!=NULL) { LPCSTR szErrorRptHash = strconv.t2a(sErrorRptHash.GetBuffer(0)); fwrite(szErrorRptHash, strlen(szErrorRptHash), 1, f); fclose(f); m_MapiSender.AddAttachment(sTmpFileName, sFileTitle); } BOOL bSend = m_MapiSender.Send(); if(!bSend) m_Assync.SetProgress(m_MapiSender.GetLastErrorMsg(), 100, false); else m_Assync.SetProgress(_T("Sent OK"), 100, false); return bSend; }
BOOL CImage::LoadBitmapFromJPEGFile(LPTSTR szFileName) { BOOL bStatus = false; struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; FILE* fp = NULL; JSAMPROW row = NULL; BITMAPINFO bmi; HDC hDC = NULL; cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); _TFOPEN_S(fp, szFileName, _T("rb")); if (!fp) { goto cleanup; } jpeg_stdio_src(&cinfo, fp); jpeg_read_header(&cinfo, TRUE); jpeg_start_decompress(&cinfo); row = new BYTE[cinfo.output_width*3+10]; hDC = GetDC(NULL); { CAutoLock lock(&m_csLock); if(m_bLoadCancelled) goto cleanup; m_hBitmap = CreateCompatibleBitmap(hDC, cinfo.output_width, cinfo.output_height); } memset(&bmi, 0, sizeof(bmi)); bmi.bmiHeader.biSize = sizeof(bmi); bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biWidth = cinfo.output_width; bmi.bmiHeader.biHeight = cinfo.output_height; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biSizeImage = cinfo.output_width*cinfo.output_height*3; while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, &row, 1); if(cinfo.out_color_components==3) { // Convert RGB to BGR UINT i; for(i=0; i<cinfo.output_width; i++) { BYTE tmp = row[i*3+0]; row[i*3+0] = row[i*3+2]; row[i*3+2] = tmp; } } else { // Convert grayscale to BGR int i; for(i=cinfo.output_width-1; i>=0; i--) { row[i*3+0] = row[i]; row[i*3+1] = row[i]; row[i*3+2] = row[i]; } } { CAutoLock lock(&m_csLock); int n = SetDIBits(hDC, m_hBitmap, cinfo.output_height-cinfo.output_scanline, 1, row, &bmi, DIB_RGB_COLORS); if(n==0) goto cleanup; } } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); bStatus = true; cleanup: if(row) delete [] row; if(!bStatus) { Destroy(); } if(fp!=NULL) { fclose(fp); fp = NULL; } return bStatus; }
BOOL CImage::LoadBitmapFromPNGFile(LPTSTR szFileName) { BOOL bStatus = FALSE; FILE *fp = NULL; const int number = 8; png_byte header[number]; png_structp png_ptr = NULL; png_infop info_ptr = NULL; png_infop end_info = NULL; png_uint_32 rowbytes = 0; png_uint_32 width = 0; png_uint_32 height = 0; png_bytep row = NULL; int y = 0; BITMAPINFO* pBMI = NULL; HDC hDC = NULL; _TFOPEN_S(fp, szFileName, _T("rb")); if (!fp) { return FALSE; } fread(header, 1, number, fp); if(png_sig_cmp(header, 0, number)) { goto cleanup; } png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) goto cleanup; if (setjmp(png_ptr->jmpbuf)) goto cleanup; info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) goto cleanup; end_info = png_create_info_struct(png_ptr); if (!end_info) goto cleanup; png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, number); // Read PNG information png_read_info(png_ptr, info_ptr); // Get count of bytes per row rowbytes = png_get_rowbytes(png_ptr, info_ptr); row = new png_byte[rowbytes]; width = png_get_image_width(png_ptr, info_ptr); height = png_get_image_height(png_ptr, info_ptr); if(info_ptr->channels==3) { png_set_strip_16(png_ptr); png_set_packing(png_ptr); png_set_bgr(png_ptr); } hDC = GetDC(NULL); { CAutoLock lock(&m_csLock); if(m_bLoadCancelled) goto cleanup; m_hBitmap = CreateCompatibleBitmap(hDC, width, height); } pBMI = (BITMAPINFO*)new BYTE[sizeof(BITMAPINFO)+256*4]; memset(pBMI, 0, sizeof(BITMAPINFO)+256*4); pBMI->bmiHeader.biSize = sizeof(BITMAPINFO); pBMI->bmiHeader.biBitCount = 8*info_ptr->channels; pBMI->bmiHeader.biWidth = width; pBMI->bmiHeader.biHeight = height; pBMI->bmiHeader.biPlanes = 1; pBMI->bmiHeader.biCompression = BI_RGB; pBMI->bmiHeader.biSizeImage = rowbytes*height; if( info_ptr->channels == 1 ) { RGBQUAD* palette = pBMI->bmiColors; int i; for( i = 0; i < 256; i++ ) { palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i; palette[i].rgbReserved = 0; } palette[256].rgbBlue = palette[256].rgbGreen = palette[256].rgbRed = 255; } for(y=height-1; y>=0; y--) { png_read_rows(png_ptr, &row, png_bytepp_NULL, 1); { CAutoLock lock(&m_csLock); int n = SetDIBits(hDC, m_hBitmap, y, 1, row, pBMI, DIB_RGB_COLORS); if(n==0) goto cleanup; } } /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ png_read_end(png_ptr, info_ptr); bStatus = TRUE; cleanup: if(fp!=NULL) { fclose(fp); } if(png_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)&info_ptr, (png_infopp)&end_info); } if(row) { delete [] row; } if(pBMI) { delete [] pBMI; } if(!bStatus) { Destroy(); } return bStatus; }