CreateFile API call in VB .NET

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Terry Olsen

    #1

    CreateFile API call in VB .NET

    I'm trying to create a disk image of a floppy disk. Since I can't open
    the device using the system.io methods, i'm trying to use the CreateFile
    API to get a handle for me. But the call fails (returning a -1).
    Here's the code:

    Const GENERIC_READ = &H80000000
    Const OPEN_EXISTING = 3
    Const FILE_SHARE_READ = &H1
    Const FILE_SHARE_WRIT E = &H2
    Const FILE_ATTRIBUTE_ NORMAL = &H80
    Const FILE_FLAG_NO_BU FFERING = &H20000000

    Declare Function CreateFile Lib "kernel32"
    Alias "CreateFile A" (ByVal lpFileName As String, _
    ByVal dwDesiredAccess As Long, _
    ByVal dwShareMode As Long, _
    ByVal lpSecurityAttri butes As Long, _
    ByVal dwCreationDistr ibution As Long, _
    ByVal dwFlagsAndAttri butes As Long, _
    ByVal hTemplateFile As Long) As IntPtr

    Dim fh As IntPtr = CreateFile("\\. \A:", _
    GENERIC_READ, _
    FILE_SHARE_READ Or FILE_SHARE_WRIT E, _
    0, _
    OPEN_EXISTING, _
    FILE_ATTRIBUTE_ NORMAL Or FILE_FLAG_NO_BU FFERING, _
    0)

    I'm hoping someone can tell me what's wrong here and help me fix it so I
    get a valid handle returned.

    *** Sent via Developersdex http://www.developersdex.com ***
  • Herfried K. Wagner [MVP]

    #2
    Re: CreateFile API call in VB .NET

    "Terry Olsen" <tolsen64@hotma il.com> schrieb:[color=blue]
    > I'm trying to create a disk image of a floppy disk. Since I can't open
    > the device using the system.io methods, i'm trying to use the CreateFile
    > API to get a handle for me. But the call fails (returning a -1).
    > Here's the code:
    >
    > Const GENERIC_READ = &H80000000
    > Const OPEN_EXISTING = 3
    > Const FILE_SHARE_READ = &H1
    > Const FILE_SHARE_WRIT E = &H2
    > Const FILE_ATTRIBUTE_ NORMAL = &H80
    > Const FILE_FLAG_NO_BU FFERING = &H20000000[/color]

    Declare all of the constants as 'Int32'.
    [color=blue]
    > Declare Function CreateFile Lib "kernel32"
    > Alias "CreateFile A" (ByVal lpFileName As String, _
    > ByVal dwDesiredAccess As Long, _
    > ByVal dwShareMode As Long, _
    > ByVal lpSecurityAttri butes As Long, _
    > ByVal dwCreationDistr ibution As Long, _
    > ByVal dwFlagsAndAttri butes As Long, _
    > ByVal hTemplateFile As Long) As IntPtr[/color]

    Use this declaration instead (untested):

    \\\
    Imports System.Runtime. InteropServices
    ..
    ..
    ..
    Private Declare Auto Function CreateFile Lub "kernel32.d ll" ( _
    ByVal lpFileName As String, _
    ByVal dwDesiredAccess As Int32, _
    ByVal dwShareMode As Int32, _
    ByRef lpSecurityAttri butes As SECURITY_ATTRIB UTES, _
    ByVal dwCreationDistr ibution As Int32, _
    ByVal dwFlagsAndAttri butes As Int32, _
    ByVal hTemplateFile As IntPtr _
    ) As IntPtr

    <StructLayout(L ayoutKind.Seque ntial)> _
    Private Structure SECURITY_ATTRIB UTES
    Public nLength As Int32
    Public lpSecurityDescr iptor As IntPtr
    Public bInheritHandle As Boolean
    End Structure
    ///

    --
    M S Herfried K. Wagner
    M V P <URL:http://dotnet.mvps.org/>
    V B <URL:http://classicvb.org/petition/>

    Comment

    • Terry Olsen

      #3
      Re: CreateFile API call in VB .NET

      The error code being returned from Err.lastDLLErro r is 87, which equates
      to "The parameter is incorrect." Now which parameter are we talking
      about? Still can't figure it out.

      *** Sent via Developersdex http://www.developersdex.com ***

      Comment

      • Rocky

        #4
        Re: CreateFile API call in VB .NET

        Give this a try,

        Declare Auto Function CreateFile Lib "kernel32.d ll" (ByVal lpFileName As
        String, _
        ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer, _
        ByVal lpSecurityAttri butes As IntPtr, ByVal dwCreationDispo sition As
        Integer, _
        ByVal dwFlagsAndAttri butes As Integer, ByVal hTemplateFile As IntPtr)
        As IntPtr

        Dim handle As IntPtr
        handle = CreateFile("\\. \\A:", GENERIC_READ, FILE_SHARE_READ Or
        FILE_SHARE_WRIT E, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_ NORMAL,
        IntPtr.Zero)


        "Terry Olsen" <tolsen64@hotma il.com> wrote in message
        news:e9DU29W4FH A.3976@TK2MSFTN GP15.phx.gbl...[color=blue]
        > The error code being returned from Err.lastDLLErro r is 87, which equates
        > to "The parameter is incorrect." Now which parameter are we talking
        > about? Still can't figure it out.
        >
        > *** Sent via Developersdex http://www.developersdex.com ***[/color]


        Comment

        • Terry Olsen

          #5
          Re: CreateFile API call in VB .NET

          Thanks Herfried & Rocky. I'm getting a valid handle now with the
          following function call:

          Dim fh As IntPtr = CreateFile("\\. \A:", _
          GENERIC_READ, _
          FILE_SHARE_READ , _
          IntPtr.Zero, _
          OPEN_EXISTING, _
          FILE_ATTRIBUTE_ NORMAL Or FILE_FLAG_NO_BU FFERING, _
          0)

          All variables are Int32. Great. Now when I try to open a stream for
          reading using:

          Dim sr As New FileStream(fh, FileAccess.Read )

          I get...

          Unhandled Exception: System.IO.IOExc eption: The parameter is incorrect.

          at System.IO.__Err or.WinIOError(I nt32 errorCode, String str)
          at System.IO.FileS tream.get_Lengt h()
          at System.IO.FileS tream..ctor(Int Ptr handle, FileAccess access, Boolean
          ownsHandle, Int32 bufferSize, Boolean isAsync)
          at System.IO.FileS tream..ctor(Int Ptr handle, FileAccess access)


          *** Sent via Developersdex http://www.developersdex.com ***

          Comment

          • Rocky

            #6
            Re: CreateFile API call in VB .NET

            You have to use the ReadFile API

            Private Declare Function ReadFile Lib "kernel32.d ll" (ByVal hFile As
            IntPtr, ByVal lpBuffer As IntPtr, ByVal nNumberOfBytesT oRead As Int32, ByRef
            lpNumberOfBytes Read As Int32, ByVal lpOverlapped As IntPtr) As Int32


            "Terry Olsen" <tolsen64@hotma il.com> wrote in message
            news:OclFk8X4FH A.1416@TK2MSFTN GP09.phx.gbl...[color=blue]
            > Thanks Herfried & Rocky. I'm getting a valid handle now with the
            > following function call:
            >
            > Dim fh As IntPtr = CreateFile("\\. \A:", _
            > GENERIC_READ, _
            > FILE_SHARE_READ , _
            > IntPtr.Zero, _
            > OPEN_EXISTING, _
            > FILE_ATTRIBUTE_ NORMAL Or FILE_FLAG_NO_BU FFERING, _
            > 0)
            >
            > All variables are Int32. Great. Now when I try to open a stream for
            > reading using:
            >
            > Dim sr As New FileStream(fh, FileAccess.Read )
            >
            > I get...
            >
            > Unhandled Exception: System.IO.IOExc eption: The parameter is incorrect.
            >
            > at System.IO.__Err or.WinIOError(I nt32 errorCode, String str)
            > at System.IO.FileS tream.get_Lengt h()
            > at System.IO.FileS tream..ctor(Int Ptr handle, FileAccess access, Boolean
            > ownsHandle, Int32 bufferSize, Boolean isAsync)
            > at System.IO.FileS tream..ctor(Int Ptr handle, FileAccess access)
            >
            >
            > *** Sent via Developersdex http://www.developersdex.com ***[/color]


            Comment

            • Herfried K. Wagner [MVP]

              #7
              Re: CreateFile API call in VB .NET

              "Rocky" <noplace@nowher e.com> schrieb:[color=blue]
              > You have to use the ReadFile API
              >
              > Private Declare Function ReadFile Lib "kernel32.d ll" (ByVal hFile As
              > IntPtr, ByVal lpBuffer As IntPtr, ByVal nNumberOfBytesT oRead As Int32,
              > ByRef lpNumberOfBytes Read As Int32, ByVal lpOverlapped As IntPtr) As Int32[/color]

              That's true for .NET 1.0/1.1, which seem to suffer from a bug (see:
              URL:http://groups.google.de/group/micros...f91265dd847a1).
              The OP's code should work with .NET 2.0.

              --
              M S Herfried K. Wagner
              M V P <URL:http://dotnet.mvps.org/>
              V B <URL:http://classicvb.org/petition/>

              Comment

              • Rocky

                #8
                Re: CreateFile API call in VB .NET

                I just tried it out in .Net 2.0 and yes it does work.

                "Herfried K. Wagner [MVP]" <hirf-spam-me-here@gmx.at> wrote in message
                news:uSWEiIZ4FH A.268@TK2MSFTNG P10.phx.gbl...[color=blue]
                > "Rocky" <noplace@nowher e.com> schrieb:[color=green]
                >> You have to use the ReadFile API
                >>
                >> Private Declare Function ReadFile Lib "kernel32.d ll" (ByVal hFile As
                >> IntPtr, ByVal lpBuffer As IntPtr, ByVal nNumberOfBytesT oRead As Int32,
                >> ByRef lpNumberOfBytes Read As Int32, ByVal lpOverlapped As IntPtr) As
                >> Int32[/color]
                >
                > That's true for .NET 1.0/1.1, which seem to suffer from a bug (see:
                > URL:http://groups.google.de/group/micros...f91265dd847a1).
                > The OP's code should work with .NET 2.0.
                >
                > --
                > M S Herfried K. Wagner
                > M V P <URL:http://dotnet.mvps.org/>
                > V B <URL:http://classicvb.org/petition/>[/color]


                Comment

                • Terry Olsen

                  #9
                  Re: CreateFile API call in VB .NET

                  You guys have helped me to read from the floppy and create an image.
                  Thanks! Now I'm trying to create a floppy from the image. You'd think
                  it would be easy. But now i'm getting another error. Here's the code:

                  Dim buf(18432) As Byte
                  Dim fh As IntPtr = CreateFile("\\. \" & cboFloppy.Text, _
                  GENERIC_WRITE, _
                  FILE_SHARE_WRIT E, _
                  IntPtr.Zero, _
                  OPEN_EXISTING, _
                  FILE_ATTRIBUTE_ NORMAL Or FILE_FLAG_NO_BU FFERING, _
                  0)

                  If fh.ToInt32 < 0 Then
                  MsgBox("Bad Disk or No Disk in Drive. Can't continue.",
                  MsgBoxStyle.Cri tical)
                  btnCreate.Enabl ed = True
                  Exit Sub
                  End If

                  Dim sr As New FileStream(Imag eName, FileMode.Open, FileAccess.Read ,
                  FileShare.None)

                  With ProgressBar1
                  ..Minimum = 0
                  ..Maximum = 80
                  ..Value = 0
                  End With

                  For i As Integer = 1 To 80
                  sr.Read(buf, 0, 18432)
                  Dim y As Int32 = 0
                  Dim x As Int32
                  x = WriteFile(fh, buf, 18432, y, IntPtr.Zero) 'This line give me an
                  "object reference not set to an instance" message.
                  Next

                  This routine is almost identical to the routine that reads from the
                  floppy and writes to a file. This one just reads from the file and
                  attempts to write to the floppy. But I'm getting the error above. Hope
                  you can help. Thanks.

                  *** Sent via Developersdex http://www.developersdex.com ***

                  Comment

                  • Herfried K. Wagner [MVP]

                    #10
                    Re: CreateFile API call in VB .NET

                    "Terry Olsen" <tolsen64@hotma il.com> schrieb:[color=blue]
                    > x = WriteFile(fh, buf, 18432, y, IntPtr.Zero) 'This line give me an
                    > "object reference not set to an instance" message.
                    > Next[/color]

                    Post the declaration of 'WriteFile' you are using.

                    --
                    M S Herfried K. Wagner
                    M V P <URL:http://dotnet.mvps.org/>
                    V B <URL:http://classicvb.org/petition/>

                    Comment

                    • Terry Olsen

                      #11
                      Re: CreateFile API call in VB .NET

                      Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As
                      IntPtr, _
                      ByVal lpBuffer As Byte(), _
                      ByVal nNumberOfBytesT oWrite As Int32, _
                      ByVal lpNumberOfBytes Written As Int32, _
                      ByVal lpOverlapped As IntPtr) As Int32

                      *** Sent via Developersdex http://www.developersdex.com ***

                      Comment

                      • Herfried K. Wagner [MVP]

                        #12
                        Re: CreateFile API call in VB .NET

                        "Terry Olsen" <tolsen64@hotma il.com> schrieb:[color=blue]
                        > ByVal lpNumberOfBytes Written As Int32, _[/color]

                        => 'ByRef lpNumberOfBytes Written As Int32'.

                        --
                        M S Herfried K. Wagner
                        M V P <URL:http://dotnet.mvps.org/>
                        V B <URL:http://classicvb.org/petition/>

                        Comment

                        • Terry Olsen

                          #13
                          Re: CreateFile API call in VB .NET

                          Thanks! That worked. Don't know how I missed that. My ReadFile was
                          correctly declared... go figure...

                          "Herfried K. Wagner [MVP]" <hirf-spam-me-here@gmx.at> wrote in message
                          news:%23wQWDKk4 FHA.4076@TK2MSF TNGP15.phx.gbl. ..[color=blue]
                          > "Terry Olsen" <tolsen64@hotma il.com> schrieb:[color=green]
                          >> ByVal lpNumberOfBytes Written As Int32, _[/color]
                          >
                          > => 'ByRef lpNumberOfBytes Written As Int32'.
                          >
                          > --
                          > M S Herfried K. Wagner
                          > M V P <URL:http://dotnet.mvps.org/>
                          > V B <URL:http://classicvb.org/petition/>[/color]


                          Comment

                          Working...