none
Windows Server 2008 R2 AccessViolationException RRS feed

  • Question

  • Hi,

    I am new to Microsoft technologies. I am facing AccessViolationException while invoking DeviceIoControl to interact with a Driver on Windows Server 2008 R2 64bit. Same code works on Windows Server 2012 R2 64 bit. Even after reading a lot can't figure out, what's the issue. Can some please help me to fix the same?

    My application is using .NET Framework 4.5.2 and platform target Any CPU Prefer 32-bit.

    Below is my code sample of console application.

                              

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;

    namespace IOCTLPOCTest
    {
        [
        System.Runtime.InteropServices.ComVisible(false),
        System.Security.SuppressUnmanagedCodeSecurityAttribute()
        ]
        class Program
        {
            static void Main(string[] args)
            {
                IntPtr hdl = IntPtr.Zero;

                try
                {
                Console.WriteLine(string.Format("Starting..........."));

                hdl = CreateFile("\\\\.\\TestDriver", FileAccess.ReadWrite,
                FileShare.None, IntPtr.Zero, FileMode.CreateNew,
                FileOptions.None, IntPtr.Zero);

                Console.WriteLine(string.Format("Created file {0}", hdl));
                if (hdl == (IntPtr)(-1)) throw new Win32Exception();

                    int IOCTL_READ_FILE = new int();
                    // Note you get to define whatever code you want for the IOCTL
                    IOCTL_READ_FILE = CTL_CODE(40001, (int)0x902, METHOD_BUFFERED, FILE_ANY_ACCESS);

                    IOCTLDATA INIOCTLDATA = new IOCTLDATA();
                    INIOCTLDATA.securityKey = 12345;
                    INIOCTLDATA.returnCode = 0;
                    INIOCTLDATA.command = IOCTLcommand.addApp;
                    INIOCTLDATA.AppID = 6;


                    IOCTLDATA OUTIOCTLDATA = new IOCTLDATA();

    int INIOCTLDATASize = Marshal.SizeOf(INIOCTLDATA);
                    int OUTIOCTLDATASize = Marshal.SizeOf(OUTIOCTLDATA);


                    Console.WriteLine(string.Format("Before DeviceIoControl..."));


                    bool ok = DeviceIoControl(hdl, (uint)IOCTL_READ_FILE, ref INIOCTLDATA, INIOCTLDATASize, ref OUTIOCTLDATA, OUTIOCTLDATASize, IntPtr.Zero, IntPtr.Zero);

                    Console.WriteLine(string.Format("Output boolean value {0}", ok));

                    if (!ok) throw new Win32Exception();

                }
                catch (Exception ex) {
                    Console.WriteLine(string.Format("Got Exception {0}", ex.ToString()));
                }
                finally
                {
                    CloseHandle(hdl);
                }

                Thread.Sleep(60000);
            }

            public static int CTL_CODE(int DeviceType, int Function, int Method, int Access)
            {
                return (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method));
            }

            public int DEVICE_TYPE_FROM_CTL_CODE(int ctrlCode)
            {
                return (int)((ctrlCode & 0xffff0000) >> 16);
            }


            // P/Invoke:
            private const uint CTLCODE = 0xdaf52480;
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern IntPtr CreateFile(string filename, FileAccess access,
                  FileShare sharing, IntPtr SecurityAttributes, FileMode mode,
                  FileOptions options, IntPtr template
            );

            [DllImport("kernel32.dll", SetLastError = true)]
            private static extern bool DeviceIoControl(IntPtr device, uint ctlcode,
                ref IOCTLDATA inbuffer, int inbuffersize,
                ref IOCTLDATA outbuffer, int outbufferSize,
                IntPtr bytesreturned, IntPtr overlapped
            );

            [DllImport("kernel32.dll")]
            private static extern void CloseHandle(IntPtr hdl);

            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
            public struct SECURITY_ATTRIBUTES
            {
                public int nLength;             // DWORD
                public IntPtr lpSecurityDescriptor;    // LPVOID
                public int bInheritHandle;        // BOOL
            }


            private const uint SUCCESS = 0x00000000;
            private const uint INVALID_SECURITY_KEY = 0X80000001;
            private const uint INVALID_DUP_APP_ID = 0x80000002;
            private const uint INVALID_APP_ID = 0x80000003;
            private const uint INVALID_COMMAND = 0x80000004;
            private const uint COMMAND_NOT_IMPLEMENTED = 0x80000005;

            public const int
                INVALID_HANDLE_VALUE = (-1),
                NULL = 0,
                ERROR_SUCCESS = 0,
                FILE_READ_DATA = (0x0001),
                FILE_SHARE_READ = 0x00000001,
                OPEN_EXISTING = 3,
                GENERIC_READ = unchecked((int)0x80000000),
                METHOD_BUFFERED = 0,
                METHOD_NEITHER = 3,
                FILE_ANY_ACCESS = 0,
                FILE_DEVICE_VIRTUAL_DISK = 0x00000024;

        }

        struct  IOCTLDATA {
            public int securityKey { get; set; } //= 12345;
    public IOCTLcommand command { get; set; }
            public int AppID { get; set; }
    public int returnCode { get; set; }
        }

        enum IOCTLcommand
        {
            addApp,
            removeApp,
        };
    }

    Let me know in case you need more info.

    Thanks  & Regards,

    Puneet Garg

    Saturday, April 9, 2016 10:47 PM

All replies

  • Hi,

    I am able to solve the problem by using out keyword for output buffer and returnbytes parameters.

    Now it works with both 2012 and 2008 R2 servers.

    Thanks.

    Wednesday, April 13, 2016 1:58 PM