Note that there are some explanatory texts on larger screens.

plurals
  1. POAttempted to read or write protected memory
    text
    copied!<p>I am having problem with the MAPI class below.(original source <a href="http://www.codeproject.com/KB/IP/SendFileToNET.aspx" rel="nofollow">http://www.codeproject.com/KB/IP/SendFileToNET.aspx</a>) </p> <p>When users try to send emails using the SendMailPopup-method the email program opens correctly but after the mail window closes the program sometimes crashes with message: <code>Attempted to read or write protected memory. This is often an indication that other memory is corrupt.</code></p> <p>I suspect that that the bug is caused by the cleanup method and I managed to reduce the frequency of the crashes by using Int64 to store the pointers instead of int used in the original version. However my .net unsafe programming knowlege is rather limited so can someone help me to find out what is causing rest of the crashes</p> <p>Update: Apparently the cleanup method is not causing the exceptions because the program crashes even when it is commented out, so the only possible cause is the MAPI32.ddl sendmail method. Probably something wrong with the pointers passed to it as parameters. </p> <p>Users are using systems with 64-bit processors and 32-bit winxp.</p> <p><strong>Update:</strong></p> <p>The solutions provided in this thread did lower the frequency of crashes but did not solve the problem entirely. The only solution that worked 100 % was to write a small console application using c++ that actually made the MAPI calls. Our .NET application interfaced with mapi by firing up the console application and passing data to it using arguments.</p> <pre><code> public class MAPI { public bool AddRecipientTo(string email) { return AddRecipient(email, HowTo.MAPI_TO); } public bool AddRecipientCC(string email) { return AddRecipient(email, HowTo.MAPI_CC); } public bool AddRecipientBCC(string email) { return AddRecipient(email, HowTo.MAPI_BCC); } public void AddAttachment(string strAttachmentFileName) { m_attachments.Add(strAttachmentFileName); } public int SendMailPopup(string strSubject, string strBody) { return SendMail(strSubject, strBody, MAPI_LOGON_UI | MAPI_DIALOG); } public int SendMailDirect(string strSubject, string strBody) { return SendMail(strSubject, strBody, MAPI_LOGON_UI); } [DllImport("MAPI32.DLL")] static extern int MAPISendMail(IntPtr sess, IntPtr hwnd, MapiMessage message, int flg, int rsv); int SendMail(string strSubject, string strBody, int how) { MapiMessage msg = new MapiMessage(); msg.subject = strSubject; msg.noteText = strBody; msg.recips = GetRecipients(out msg.recipCount); msg.files = GetAttachments(out msg.fileCount); m_lastError = MAPISendMail(new IntPtr(0L), new IntPtr(0L), msg, how, 0); if (m_lastError &gt; 1) MessageBox.Show("MAPISendMail failed! " + GetLastError(), "MAPISendMail"); Cleanup(ref msg); return m_lastError; } bool AddRecipient(string email, HowTo howTo) { if (!String.IsNullOrEmpty(email)) { MapiRecipDesc recipient = new MapiRecipDesc(); recipient.recipClass = (int)howTo; recipient.name = email; m_recipients.Add(recipient); return true; } else { return false; } } IntPtr GetRecipients(out int recipCount) { recipCount = 0; if (m_recipients.Count == 0) return IntPtr.Zero; int size = Marshal.SizeOf(typeof(MapiRecipDesc)); IntPtr intPtr = Marshal.AllocHGlobal(m_recipients.Count * size); int ptr = (int)intPtr; foreach (MapiRecipDesc mapiDesc in m_recipients) { Marshal.StructureToPtr(mapiDesc, (IntPtr)ptr, false); ptr += size; } recipCount = m_recipients.Count; return intPtr; } IntPtr GetAttachments(out int fileCount) { fileCount = 0; if (m_attachments == null) return IntPtr.Zero; if ((m_attachments.Count &lt;= 0) || (m_attachments.Count &gt; maxAttachments)) return IntPtr.Zero; int size = Marshal.SizeOf(typeof(MapiFileDesc)); IntPtr intPtr = Marshal.AllocHGlobal(m_attachments.Count * size); MapiFileDesc mapiFileDesc = new MapiFileDesc(); mapiFileDesc.position = -1; int ptr = (int)intPtr; foreach (string strAttachment in m_attachments) { mapiFileDesc.name = Path.GetFileName(strAttachment); mapiFileDesc.path = strAttachment; Marshal.StructureToPtr(mapiFileDesc, (IntPtr)ptr, false); ptr += size; } fileCount = m_attachments.Count; return intPtr; } void Cleanup(ref MapiMessage msg) { try { int size = Marshal.SizeOf(typeof(MapiRecipDesc)); Int64 ptr = 0; if (msg.recips != IntPtr.Zero) { ptr = msg.recips.ToInt64(); for (int i = 0; i &lt; msg.recipCount; i++) { Marshal.DestroyStructure((IntPtr)ptr, typeof(MapiRecipDesc)); ptr += size; } Marshal.FreeHGlobal(msg.recips); } if (msg.files != IntPtr.Zero) { size = Marshal.SizeOf(typeof(MapiFileDesc)); ptr = msg.files.ToInt64(); for (int i = 0; i &lt; msg.fileCount; i++) { Marshal.DestroyStructure((IntPtr)ptr, typeof(MapiFileDesc)); ptr += size; } Marshal.FreeHGlobal(msg.files); } m_recipients.Clear(); m_attachments.Clear(); } catch (Exception e) { SmtpSender errorSender = new SmtpSender(); errorSender.SendAutomaticError(e.StackTrace + e.Message, "Virhe mapi sähköpostin lähetyksessä" + MySession.ProjectName + " Käyttäjä:" + MySession.LoginName); } } public string GetLastError() { if (m_lastError &lt;= 26) return errors[m_lastError]; return "MAPI error [" + m_lastError.ToString() + "]"; } readonly string[] errors = new string[] { "OK [0]", "User abort [1]", "Yleinen virhe sähköpostin lähettämisessä [2]", "MAPI login failure [3]", "Disk full [4]", "Insufficient memory [5]", "Access denied [6]", "-unknown- [7]", "Too many sessions [8]", "Too many files were specified [9]", "Too many recipients were specified [10]", "A specified attachment was not found [11]", "Attachment open failure [12]", "Attachment write failure [13]", "Unknown recipient [14]", "Bad recipient type [15]", "No messages [16]", "Invalid message [17]", "Text too large [18]", "Invalid session [19]", "Type not supported [20]", "A recipient was specified ambiguously [21]", "Message in use [22]", "Network failure [23]", "Invalid edit fields [24]", "Asiakkaalle ei ole määritetty sähköpostiosoitetta.", "Not supported [26]" }; List&lt;MapiRecipDesc&gt; m_recipients = new List&lt;MapiRecipDesc&gt;(); List&lt;string&gt; m_attachments = new List&lt;string&gt;(); int m_lastError = 0; const int MAPI_LOGON_UI = 0x00000001; const int MAPI_DIALOG = 0x00000008; const int maxAttachments = 20; enum HowTo { MAPI_ORIG = 0, MAPI_TO, MAPI_CC, MAPI_BCC }; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public class MapiMessage { public int reserved; public string subject; public string noteText; public string messageType; public string dateReceived; public string conversationID; public int flags; public IntPtr originator; public int recipCount; public IntPtr recips; public int fileCount; public IntPtr files; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public class MapiFileDesc { public int reserved; public int flags; public int position; public string path; public string name; public IntPtr type; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public class MapiRecipDesc { public int reserved; public int recipClass; public string name; public string address; public int eIDSize; public IntPtr entryID; } </code></pre> <p>Below is the stacktrace of the exception. It is partly in finnish, but you can still see the method names from it.</p> <p><code> kohteessa System.Windows.Forms.UnsafeNativeMethods.DispatchMessageA(MSG&amp; msg) kohteessa System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData) kohteessa System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) kohteessa System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) kohteessa System.Windows.Forms.Application.Run(Form mainForm)</code></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload