• Visitors can check out the Forum FAQ by clicking this link. You have to register before you can post: click the REGISTER link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below. View our Forum Privacy Policy.
  • Want to receive the latest contracting news and advice straight to your inbox? Sign up to the ContractorUK newsletter here. Every sign up will also be entered into a draw to WIN £100 Amazon vouchers!

Reply to: IRP problem

Collapse

You are not logged in or you do not have permission to access this page. This could be due to one of several reasons:

  • You are not logged in. If you are already registered, fill in the form below to log in, or follow the "Sign Up" link to register a new account.
  • You may not have sufficient privileges to access this page. Are you trying to edit someone else's post, access administrative features or some other privileged system?
  • If you are trying to post, the administrator may have disabled your account, or it may be awaiting activation.

Previously on "IRP problem"

Collapse

  • suityou01
    replied
    Originally posted by suityou01 View Post
    Thanks for the reply dood.

    The FIREWALL_STATUS call works but the returned values look a bit iffy. I'll fathom that out later. The IRP processing in my driver must also be more defensively coded I think. It should check the size of the buffer provided and return an error rather than BSOD.

    I am convinced the problem is with the structure declaration. And also to do with those char[16] declarations I cannot port to c#.

    Edit : May try this

    Code:
    [MarshalAs (UnmanagedType.ByValArray, SizeConst = 16)]
    byte[] sourceIP;
    [MarshalAs (UnmanagedType.ByValArray, SizeConst = 16)]
    byte[] destIP;
    Yip, that did it. Now getting data back (lawd knows what) and no bsods. Just need to marshal the buffer back to my struct.

    Leave a comment:


  • suityou01
    replied
    Originally posted by doodab View Post
    Well, that I don't know, it just seemed that the call would be expecting a bigger structure than you pass in. Perhaps allocate the right amount of memory (based on working it out) and then use Marshal.copy to shuffle data back and forth?

    The call with the FIREWALL_STATUS looks OK size wise though, does that fail as well?
    Thanks for the reply dood.

    The FIREWALL_STATUS call works but the returned values look a bit iffy. I'll fathom that out later. The IRP processing in my driver must also be more defensively coded I think. It should check the size of the buffer provided and return an error rather than BSOD.

    I am convinced the problem is with the structure declaration. And also to do with those char[16] declarations I cannot port to c#.

    Edit : May try this

    Code:
    [MarshalAs (UnmanagedType.ByValArray, SizeConst = 16)]
    byte[] sourceIP;
    [MarshalAs (UnmanagedType.ByValArray, SizeConst = 16)]
    byte[] destIP;
    Last edited by suityou01; 5 August 2010, 19:26.

    Leave a comment:


  • doodab
    replied
    Well, that I don't know, it just seemed that the call would be expecting a bigger structure than you pass in. Perhaps allocate the right amount of memory (based on working it out) and then use Marshal.copy to shuffle data back and forth?

    The call with the FIREWALL_STATUS looks OK size wise though, does that fail as well?

    Leave a comment:


  • suityou01
    replied
    Originally posted by doodab View Post
    Don't you need to specify the size of the char arrays in the c# struct?
    Sure, how?

    I tried char[16] blah;

    and it would not compile

    so I try char[] blah = new char[16];

    and it would not compile.

    At the moment the size of the buffer is 40 bytes which is woefully short of where it should be.

    I create an instance of the struct then set the char arrays to char[16] like this

    FIREWALL_MESSAGE fm = new FIREWALL_MESSAGE();
    fm.sourceIp = new char[16];
    fm.destIp = new char[16];

    still it only sizeof's to 40 bytes.

    perhaps I need to use Marshal.AllocHGlobal for the char arrays as well . . .

    ponders



    Edit : Nope that gives me a compile error Error 1

    Cannot implicitly convert type 'System.IntPtr' to 'char[]' C:\transfer\c# fork\src\PortKnox\DriverInterface\DriverInterface\ Driver.cs 302 27 DriverInterface

    Leave a comment:


  • doodab
    replied
    Don't you need to specify the size of the char arrays in the c# struct?

    Leave a comment:


  • suityou01
    started a topic IRP problem

    IRP problem

    I am writing a driver (WFP) to filter IP packets. The driver is stable (ish) in that I have managed to send packet information back to a C app using an IRP.

    I am now porting this code to C#, and when I pass in the output buffer to DeviceIOControl I get a blue screen (IRQ_NOT_LESS_OR_EQUAL)

    The minidump shows the driver tries to write to corrupt memory. So in fairness the memory I am passing in from user mode is not right.

    In C I use malloc and zero memory and it works like a charm.

    From C# I use

    Code:
    ptrOutput = Marshal.AllocHGlobal(Marshal.SizeOf(fm));
    where fm is the structure that is being populated by the driver.

    This is the structure in C

    Code:
    typedef struct FIREWALL_MESSAGE_
    {
            LIST_ENTRY listEntry;
    		int srcport;
            int destport;
            char sourceIp[16];
            char destIp[16];
    		int protocol;
    		long packetRef;
    		FWP_DIRECTION  direction; //FWP_DIRECTION Defined in Inspect.h
    		int type;
    } FIREWALL_MESSAGE;
    And this is my C# representation of it

    Code:
    public struct LIST_ENTRY
            {
                /// _LIST_ENTRY*
                public System.IntPtr Flink;
    
                /// _LIST_ENTRY*
                public System.IntPtr Blink;
            }
    
            public struct FIREWALL_MESSAGE
            {
                public LIST_ENTRY listEntry;
                public uint srcport;
                public uint destport;
                public char[] sourceIp;
                public char[] destIp;
                public uint protocol;
                public uint packetRef;
                public EFWPDIRECTION direction; //FWP_DIRECTION Defined in Inspect.h
                public uint type;
            }
    Including my declaration of LIST_ENTRY

    I have other more simple IOCTLS that pass in a structure like this

    Code:
    typedef struct FIREWALL_STATUS_
    {
    	int upTime; //Length of time the firewall has been running in time_t format
    	int packetsProcessed;
    	int packetsDropped;
    	int connectionAttemptsProcessed;
    	int connectionAttemptsRefused;
    } FIREWALL_STATUS, *PFIREWALL_STATUS;

    with the following C# implementation of it as

    Code:
    public struct FIREWALL_STATUS
            {
                uint upTime;
                uint packetsProcessed;
                uint packetsDropped;
                uint connectionAttemptsProcessed;
                uint connectionAttemptsRefused;
            }
    As I say this happens when calling DeviceIOControl and my api declaration looks like this

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool DeviceIoControl(
    Microsoft.Win32.SafeHandles.SafeFileHandle hDevice,
    uint dwIoControlCode,
    IntPtr lpInBuffer,
    uint nInBufferSize,
    [Out] IntPtr lpOutBuffer,
    uint nOutBufferSize,
    ref uint lpBytesReturned,
    IntPtr lpOverlapped);
    but this still causes a blue screen.

    The call to the api looks like this

    Code:
            private bool sendIOControl(uint ioctlCode, object inputBuffer, ref FIREWALL_STATUS fs)
            {
                uint bytesReturned = 0;
                uint inputBufferSize = 0;
                uint outputBufferSize = 0;
                IntPtr ptrOutput = IntPtr.Zero;
                IntPtr ptrInput = IntPtr.Zero;
    
                bool retVal = false;
                ptrOutput = Marshal.AllocHGlobal(Marshal.SizeOf(fs));
    
                if (inputBuffer != null)
                {
                    inputBufferSize = (uint)Marshal.SizeOf(inputBuffer);
                }
    
                outputBufferSize = (uint)Marshal.SizeOf(fs);
    
                retVal = DeviceIoControl(hDriver, ioctlCode, ptrInput, inputBufferSize, ptrOutput, outputBufferSize, ref bytesReturned, IntPtr.Zero);
                return retVal;
            }
    As I say I am totally baffled so if anyone on here has written drivers and accessed them from a high level interpreted language such as C# your insight would be appreciated.

    As I say, works perfectly from C.

Working...
X