Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CreateFile API call in VB .NET

199 views
Skip to first unread message

Terry Olsen

unread,
Nov 4, 2005, 1:04:05 PM11/4/05
to
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_WRITE = &H2
Const FILE_ATTRIBUTE_NORMAL = &H80
Const FILE_FLAG_NO_BUFFERING = &H20000000

Declare Function CreateFile Lib "kernel32"
Alias "CreateFileA" (ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, _
ByVal dwShareMode As Long, _
ByVal lpSecurityAttributes As Long, _
ByVal dwCreationDistribution As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long) As IntPtr

Dim fh As IntPtr = CreateFile("\\.\A:", _
GENERIC_READ, _
FILE_SHARE_READ Or FILE_SHARE_WRITE, _
0, _
OPEN_EXISTING, _
FILE_ATTRIBUTE_NORMAL Or FILE_FLAG_NO_BUFFERING, _
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]

unread,
Nov 4, 2005, 1:37:16 PM11/4/05
to
"Terry Olsen" <tols...@hotmail.com> schrieb:

> 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_WRITE = &H2
> Const FILE_ATTRIBUTE_NORMAL = &H80
> Const FILE_FLAG_NO_BUFFERING = &H20000000

Declare all of the constants as 'Int32'.

> Declare Function CreateFile Lib "kernel32"
> Alias "CreateFileA" (ByVal lpFileName As String, _
> ByVal dwDesiredAccess As Long, _
> ByVal dwShareMode As Long, _
> ByVal lpSecurityAttributes As Long, _
> ByVal dwCreationDistribution As Long, _
> ByVal dwFlagsAndAttributes As Long, _
> ByVal hTemplateFile As Long) As IntPtr

Use this declaration instead (untested):

\\\
Imports System.Runtime.InteropServices
.
.
.
Private Declare Auto Function CreateFile Lub "kernel32.dll" ( _


ByVal lpFileName As String, _

ByVal dwDesiredAccess As Int32, _
ByVal dwShareMode As Int32, _
ByRef lpSecurityAttributes As SECURITY_ATTRIBUTES, _
ByVal dwCreationDistribution As Int32, _
ByVal dwFlagsAndAttributes As Int32, _
ByVal hTemplateFile As IntPtr _
) As IntPtr

<StructLayout(LayoutKind.Sequential)> _
Private Structure SECURITY_ATTRIBUTES
Public nLength As Int32
Public lpSecurityDescriptor 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/>

Terry Olsen

unread,
Nov 4, 2005, 1:42:07 PM11/4/05
to
The error code being returned from Err.lastDLLError is 87, which equates
to "The parameter is incorrect." Now which parameter are we talking
about? Still can't figure it out.

Rocky

unread,
Nov 4, 2005, 2:22:50 PM11/4/05
to
Give this a try,

Declare Auto Function CreateFile Lib "kernel32.dll" (ByVal lpFileName As
String, _
ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer, _
ByVal lpSecurityAttributes As IntPtr, ByVal dwCreationDisposition As
Integer, _
ByVal dwFlagsAndAttributes As Integer, ByVal hTemplateFile As IntPtr)
As IntPtr

Dim handle As IntPtr
handle = CreateFile("\\.\\A:", GENERIC_READ, FILE_SHARE_READ Or
FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero)


"Terry Olsen" <tols...@hotmail.com> wrote in message
news:e9DU29W4...@TK2MSFTNGP15.phx.gbl...

Terry Olsen

unread,
Nov 4, 2005, 3:34:21 PM11/4/05
to
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_BUFFERING, _
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.IOException: The parameter is incorrect.

at System.IO.__Error.WinIOError(Int32 errorCode, String str)
at System.IO.FileStream.get_Length()
at System.IO.FileStream..ctor(IntPtr handle, FileAccess access, Boolean
ownsHandle, Int32 bufferSize, Boolean isAsync)
at System.IO.FileStream..ctor(IntPtr handle, FileAccess access)

Rocky

unread,
Nov 4, 2005, 4:13:04 PM11/4/05
to
You have to use the ReadFile API

Private Declare Function ReadFile Lib "kernel32.dll" (ByVal hFile As
IntPtr, ByVal lpBuffer As IntPtr, ByVal nNumberOfBytesToRead As Int32, ByRef
lpNumberOfBytesRead As Int32, ByVal lpOverlapped As IntPtr) As Int32


"Terry Olsen" <tols...@hotmail.com> wrote in message

news:OclFk8X4...@TK2MSFTNGP09.phx.gbl...

Herfried K. Wagner [MVP]

unread,
Nov 4, 2005, 5:50:34 PM11/4/05
to
"Rocky" <nop...@nowhere.com> schrieb:

> You have to use the ReadFile API
>
> Private Declare Function ReadFile Lib "kernel32.dll" (ByVal hFile As
> IntPtr, ByVal lpBuffer As IntPtr, ByVal nNumberOfBytesToRead As Int32,
> ByRef lpNumberOfBytesRead As Int32, ByVal lpOverlapped As IntPtr) As Int32

That's true for .NET 1.0/1.1, which seem to suffer from a bug (see:
URL:http://groups.google.de/group/microsoft.public.dotnet.framework.interop/msg/33df91265dd847a1).
The OP's code should work with .NET 2.0.

Rocky

unread,
Nov 4, 2005, 6:47:56 PM11/4/05
to
I just tried it out in .Net 2.0 and yes it does work.

"Herfried K. Wagner [MVP]" <hirf-spa...@gmx.at> wrote in message
news:uSWEiIZ...@TK2MSFTNGP10.phx.gbl...

Terry Olsen

unread,
Nov 4, 2005, 9:52:02 PM11/4/05
to
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_WRITE, _


IntPtr.Zero, _
OPEN_EXISTING, _
FILE_ATTRIBUTE_NORMAL Or FILE_FLAG_NO_BUFFERING, _
0)

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

Dim sr As New FileStream(ImageName, 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.

Herfried K. Wagner [MVP]

unread,
Nov 5, 2005, 6:17:19 AM11/5/05
to
"Terry Olsen" <tols...@hotmail.com> schrieb:

> x = WriteFile(fh, buf, 18432, y, IntPtr.Zero) 'This line give me an
> "object reference not set to an instance" message.
> Next

Post the declaration of 'WriteFile' you are using.

Terry Olsen

unread,
Nov 5, 2005, 1:35:55 PM11/5/05
to
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As
IntPtr, _
ByVal lpBuffer As Byte(), _
ByVal nNumberOfBytesToWrite As Int32, _
ByVal lpNumberOfBytesWritten As Int32, _

ByVal lpOverlapped As IntPtr) As Int32

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

Herfried K. Wagner [MVP]

unread,
Nov 5, 2005, 2:53:13 PM11/5/05
to
"Terry Olsen" <tols...@hotmail.com> schrieb:

> ByVal lpNumberOfBytesWritten As Int32, _

=> 'ByRef lpNumberOfBytesWritten As Int32'.

Terry Olsen

unread,
Nov 5, 2005, 10:33:17 PM11/5/05
to
Thanks! That worked. Don't know how I missed that. My ReadFile was
correctly declared... go figure...

"Herfried K. Wagner [MVP]" <hirf-spa...@gmx.at> wrote in message

news:%23wQWDKk...@TK2MSFTNGP15.phx.gbl...

0 new messages