title: Access Violation in C# - winmm.dll ntdll.dll
body: <p>I have an application which basically does three things:</p>
  
  <ol>
  <li>Show an image to the user</li>
  <li>Play a 1-2 second sound (wav) to the user</li>
  <li>Record microphone input for 4 seconds (while sound is playing)</li>
  </ol>
  
  <p>This happens 280 times per user, and all of the recordings are saved in a directory for each user. However, 2 out of the last 18 runs of the program, it crashed from an unhandled exception with code c0000005 (which is described as an access violation) in module ntdll.dll. The only unmanaged api call I'm using is mciSendString from winmm.dll to get the duration of wav files and do the recording. Playback is done using an instance of WindowsMediaPlayer. </p>
  
  <p>The crashes seem to be random, and both happened on the same machine (3 are being used). These are my questions: Is ntdll.dll really the source of the exception? Am I correct in understanding the access violation is an invalid memory access? And how could that happen with a C# program running in the .NET virtual machine?</p>
  
  <p>By request here is one class from which I invoke mciSendString</p>
  
  <pre><code>public class JE_SR
  {
      [DllImport("winmm.dll", EntryPoint = "mciSendStringA", 
          CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
      private static extern uint mciSendString(string lpstrCommand, 
          string lpstrReturnString, int uReturnLength, int hwndCallback);
  
      [DllImport("winmm.dll", CharSet = CharSet.Auto)]
      private static extern int mciGetErrorString(uint errorCode, 
          StringBuilder errorText, int errorTextSize);
  
  
      private static bool recording = false;
      public static uint lastResult;
  
      public static void startRecording()
      {
          if (recording)
          {
              return;
          }
  
          tryMCISendString("open new Type waveaudio Alias recsound", "", 0, 0);
          tryMCISendString("record recsound", "", 0, 0);
  
          recording = true;
      }
  
      public static void stopRecording(string file)
      {
          if (!recording)
          {
              return;
          }
  
          if (!file.Equals(""))
          {
              tryMCISendString("save recsound " + file, "", 0, 0);
              tryMCISendString("close recsound ", "", 0, 0);
          }
          else
          {
              tryMCISendString("close all", "", 0, 0);
          }
  
          recording = false;
      }
  
      public static void tryMCISendString(string lpstrCommand,
          string lpstrReturnString, int uReturnLength, int hwndCallback)
      {
          lastResult = mciSendString(lpstrCommand, lpstrReturnString, uReturnLength, hwndCallback);
  
          StringBuilder error = new StringBuilder(256);
          if(lastResult != 0)
          {
              mciGetErrorString(lastResult, error, error.Length);
              JE_Log.logMessage("MCIERROR(JE_SR): " + error.ToString());
          }
      }
  }
  </code></pre>
  
  <p>Let me know if there are other relevant details I should include...</p>