Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. .NET (Core and Framework)
  4. [VB.NET 2008] How to use DeviceIoControl function?

[VB.NET 2008] How to use DeviceIoControl function?

Scheduled Pinned Locked Moved .NET (Core and Framework)
questioncsharpc++com
5 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    steve_9496613
    wrote on last edited by
    #1

    Hello everybody, I need to use the function DeviceIoControl to monitor the status of a COM port (RS485) but I don't know how to do. I have declared the functions:

    _
    Shared Function DeviceIoControl(ByVal hDevice As Integer, ByVal dwIoControlCode As Integer, _
    ByVal lpInBuffer As String, ByVal nInBufferSize As Integer, _
    ByVal lpOutBuffer() As Byte, ByVal nOutBufferSize As Integer, _
    ByRef lpBytesReturned As Integer, ByVal lpOverlapped As Integer) As Integer
    End Function

    Private Declare Function CreateFile Lib "coredll.dll" _
    (ByVal lpFileName As String, ByVal dwDesiredAccess As Int32, _
    ByVal dwShareMode As Int32, ByVal lpSecurityAttributes As IntPtr, _
    ByVal dwCreationDisposition As Int32, ByVal dwFlagsAndAttributes As Int32, _
    ByVal hTemplateFile As IntPtr) As IntPtr

    Declare Function CloseHandle Lib "coredll.dll" (ByVal hObject As IntPtr) As Boolean

    I use CreateFile (it works) to get an handle to the COM port and I pass it to DeviceIoControl:

    Const FILE_SHARE_READ As Integer = &H1
    Const FILE_SHARE_WRITE As Integer = &H2
    Const GENERIC_READ As Integer = &H80000000
    Const GENERIC_WRITE As Integer = &H40000000

    Dim portPtr As IntPtr
    Dim ris As Boolean
    Dim InBuffer As String
    Dim OutBuffer(100) As Byte
    Dim BytesReturned, Overlapped As Int32

    portPtr = CreateFile(com.PortName & ":", GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)

    ris = DeviceIoControl(portPtr.ToInt32, IOCTL_SERIAL_GET_COMMSTATUS, InBuffer, InBuffer.Length, OutBuffer, OutBuffer.Count, BytesReturned, Overlapped)

    CloseHandle(portPtr)

    I don't know what must be the value of IOCTL_SERIAL_GET_COMMSTATUS and I'm not sure that I'm using DeviceIoControl in the right way. I have found some information only in C++ like:

    #define IOCTL_SERIAL_GET_COMMSTATUS CTL_CODE(FILE_DEVICE_SERIAL_PORT, 27, METHOD_BUFFERED, FILE_ANY_ACCESS)

    but how can I use it in VB.NET? And then, DeviceIoControl should fill a SERIAL_STATUS structure:

    typedef struct _SERIAL_STATUS {
    ULONG Errors;
    ULONG HoldReasons;
    ULONG AmountInInQueue;
    ULONG AmountInOutQueue;
    BOOLEAN EofReceived;
    BOOLEAN WaitForImmediate;
    } SERIAL_STATUS, *PSERIAL_STATUS;

    but a struct

    D 1 Reply Last reply
    0
    • S steve_9496613

      Hello everybody, I need to use the function DeviceIoControl to monitor the status of a COM port (RS485) but I don't know how to do. I have declared the functions:

      _
      Shared Function DeviceIoControl(ByVal hDevice As Integer, ByVal dwIoControlCode As Integer, _
      ByVal lpInBuffer As String, ByVal nInBufferSize As Integer, _
      ByVal lpOutBuffer() As Byte, ByVal nOutBufferSize As Integer, _
      ByRef lpBytesReturned As Integer, ByVal lpOverlapped As Integer) As Integer
      End Function

      Private Declare Function CreateFile Lib "coredll.dll" _
      (ByVal lpFileName As String, ByVal dwDesiredAccess As Int32, _
      ByVal dwShareMode As Int32, ByVal lpSecurityAttributes As IntPtr, _
      ByVal dwCreationDisposition As Int32, ByVal dwFlagsAndAttributes As Int32, _
      ByVal hTemplateFile As IntPtr) As IntPtr

      Declare Function CloseHandle Lib "coredll.dll" (ByVal hObject As IntPtr) As Boolean

      I use CreateFile (it works) to get an handle to the COM port and I pass it to DeviceIoControl:

      Const FILE_SHARE_READ As Integer = &H1
      Const FILE_SHARE_WRITE As Integer = &H2
      Const GENERIC_READ As Integer = &H80000000
      Const GENERIC_WRITE As Integer = &H40000000

      Dim portPtr As IntPtr
      Dim ris As Boolean
      Dim InBuffer As String
      Dim OutBuffer(100) As Byte
      Dim BytesReturned, Overlapped As Int32

      portPtr = CreateFile(com.PortName & ":", GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)

      ris = DeviceIoControl(portPtr.ToInt32, IOCTL_SERIAL_GET_COMMSTATUS, InBuffer, InBuffer.Length, OutBuffer, OutBuffer.Count, BytesReturned, Overlapped)

      CloseHandle(portPtr)

      I don't know what must be the value of IOCTL_SERIAL_GET_COMMSTATUS and I'm not sure that I'm using DeviceIoControl in the right way. I have found some information only in C++ like:

      #define IOCTL_SERIAL_GET_COMMSTATUS CTL_CODE(FILE_DEVICE_SERIAL_PORT, 27, METHOD_BUFFERED, FILE_ANY_ACCESS)

      but how can I use it in VB.NET? And then, DeviceIoControl should fill a SERIAL_STATUS structure:

      typedef struct _SERIAL_STATUS {
      ULONG Errors;
      ULONG HoldReasons;
      ULONG AmountInInQueue;
      ULONG AmountInOutQueue;
      BOOLEAN EofReceived;
      BOOLEAN WaitForImmediate;
      } SERIAL_STATUS, *PSERIAL_STATUS;

      but a struct

      D Offline
      D Offline
      David Knechtges
      wrote on last edited by
      #2

      Is there a reason why you cannot use the SerialPort class within .NET? I use that for working with RS-485 ports in my projects. I use C# so my examples wouldn't help you unless you wanted to translate. In any case look here: http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.aspx[^]

      S 1 Reply Last reply
      0
      • D David Knechtges

        Is there a reason why you cannot use the SerialPort class within .NET? I use that for working with RS-485 ports in my projects. I use C# so my examples wouldn't help you unless you wanted to translate. In any case look here: http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.aspx[^]

        S Offline
        S Offline
        steve_9496613
        wrote on last edited by
        #3

        Thank you David, the reason I need to use DeviceIoControl is to catch the UART framing error that happens when I receive a DMX512 data packet. I use the SerialPort class in trasmission without problem because I can create a correct DMX data packet with the starting break (line low - zero - at least for 88 µs) but when I receive data I can't get the break that starts the packet, I just get one zero, it doesn't metter how long the break is, but this break causes a framing error, so, if I get the framing error I get the start of the data packet.

        D 1 Reply Last reply
        0
        • S steve_9496613

          Thank you David, the reason I need to use DeviceIoControl is to catch the UART framing error that happens when I receive a DMX512 data packet. I use the SerialPort class in trasmission without problem because I can create a correct DMX data packet with the starting break (line low - zero - at least for 88 µs) but when I receive data I can't get the break that starts the packet, I just get one zero, it doesn't metter how long the break is, but this break causes a framing error, so, if I get the framing error I get the start of the data packet.

          D Offline
          D Offline
          David Knechtges
          wrote on last edited by
          #4

          The SerialPort class has an ErrorReceived event, which contains the framing error. So you could use that as a way to start reading the packet then. http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.errorreceived.aspx[^]

          S 1 Reply Last reply
          0
          • D David Knechtges

            The SerialPort class has an ErrorReceived event, which contains the framing error. So you could use that as a way to start reading the packet then. http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.errorreceived.aspx[^]

            S Offline
            S Offline
            steve_9496613
            wrote on last edited by
            #5

            Yes, I tried to use the ErrorReceived event but it doesn't seem to work. I use the DataReceived event to receive data and it works but I get no error, on the other hand I read in the help that:

            ...
            PinChanged, DataReceived, and ErrorReceived events may be called out of order, and there may be a slight delay between when the underlying stream reports the error and when code can when the event handler is executed. Only one event handler can execute at a time.
            ...

            However, I found another way using API and p/invoke: I use the function WaitCommEvent() to get directly the break instaed of the framing error. This solution was suggested by Bruce Eitman in the MSDN Windows Embedded Compact forum and I found a good example in the article "Smart Device Print Engine for Compact Framework" by Orkun GEDiK here in CodeProject. Thanks anyway for your interest and for your time.

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups