views:

198

answers:

2

I am running the following scenerio:

SafeFileHandle handle = Win32API.CreateFile((deviceName + "\\" + pipeName),
                           DesiredAccess.GENERIC_WRITE | DesiredAccess.GENERIC_READ,
                           ShareMode.FILE_SHARE_WRITE | ShareMode.FILE_SHARE_READ,
                           IntPtr.Zero,
                           CreationDisposition.OPEN_EXISTING,
                           FlagsAndAttributes.FILE_ATTRIBUTE_NORMAL | FlagsAndAttributes.FILE_FLAG_OVERLAPPED,
                           IntPtr.Zero); // Marshal.GetLastWin32Error() returns 0 (success)

bool pass = Win32API.WriteFile(writeHandle, message.ToArray(), (uint)message.Count, ref bytes_written, ref over_lapped);

pass is false but to be expected since im running overlapped.
The problem is Marshal.GetLastWin32Error() doesnt return ERROR_IO_PENDING it returns ERROR_ALREADY_EXISTS. Which is weird to me because the error didnt show that when I created the file, but when I write it shows up. Now I am trying to figure out how to close the handle that I dont seem to have access to or atleast get an explanation as to why this is happening.

EDIT: Ok, I have norrowed the problem down and I know what is causing the problem.

  private void ErrorOccurred(string detailedError)
  {
     lock (mLogLock)
     {
        try
        {
           System.IO.File.AppendAllText("Device" + mDeviceHandle + "Log.txt",
           DateTime.Now.ToLongTimeString() + ": " + detailedError + Environment.NewLine);
        }
        catch (Exception ex)
        {
           System.Windows.Forms.MessageBox.Show(ex.Message);
        }
     }
  }

Apparently, internally the AppendAllText call is creating an error. Should I reset the error after this log call? I guess this would have been helpful to know that the framework doesnt reset low level calls in the internal workings of its functions. Ahh, you learn something new every day.

I guess the new question I have is, should I reset the low level error after this call, or is there some other way to log output (not using 3rd party tools like log4Net or getting fancy with the Debug.Trace output)? Bascially someway to open a file for appending that doesnt affect the Marshal.GetLastWin32Error(); output.

A: 

Marshal.GetLastWin32Error() should be the very first thing you do after the Win32API.WriteFile() call. Don't do anything else, e.g. any logging etc, between the WriteFile() and GetLastWin32Error() calls.

user9876
I understand that part now.
SwDevMan81
A: 

Are you using SetLastError = True in the DllImport declaration?

devoured elysium
I have the following over all extern operations: [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
SwDevMan81