469,117 Members | 1,342 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,117 developers. It's quick & easy.

Issues with API function ReadFile

Hello everyone,

I have been stuck with this problem for quite some time now. I am working in VB.NET, using framework 1.0. I have to keep the compatibility down to the original .NET framework as much as possible. I am forced to use API calls for several functions, one of which is ReadFile. The reason is because the framework seems to use ANSI versions of all API functions, limiting the MAX_PATH for filenames to about 260 chars for everything in System.IO. API Wide functions (Unicode) do not have this limitation.

I am having issues implementing the ReadFile function. I seem to only get various exceptions whenever I try to use it. It's declared as follows:

<DllImport("kernel32", EntryPoint:="ReadFile", CharSet:=CharSet.Unicode, SetLastError:=True, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)_
Shared Function ReadFile(ByVal hFile As Integer, ByRef lpBuffer As Object, _
ByVal nNumberOfBytesToRead As Integer, ByRef lpNumberOfBytesRead As Integer, _
ByRef lpOverlapped As OVERLAPPED) As Integer

End Function

I believe the issue is with the lpBuffer arguement. It's an <outarguement that basically populates a buffer with the bytes read from the file. In C++ its declared as a long void pointer.

I have tried various ways of using this function, passing various types of variables to it. There is always an exception though. For example, this implementation throws an System.ExecutionEngineException exception.

Dim cBuff(4096) as Char
for i = 0 to cBuff.Length -1
cBuff(i) = " "
Next
iRetVal = ReadFile(hFlHandle, cBuff, 100, iBytesRead, OL)

OL, iBytesRead, and hFlHandle are all declared eariler. The hFlHandle is valid.

When I use a string for the buffer, I get the "System.Runtime.InteropServices.InvalidOleVariantT ypeException: Specified OLE variant is invalid" exception.

Dim sBuffer as String = space(100)
iRetVal = ReadFile(hFlHandle, sBufferPtr, sBuffer.Length, iBytesRead, OL)

I am not entirely sure what the problem is. I must be missing something. Has anyone used the ReadFile function (or anything that requires an LPVOID passed to it) in VB.NET? Can anyone shine some light on this?

Thanks,

Dmitry
Sep 26 '08 #1
15 5294

This group (winapi) is for VB (mainly v. 5 and 6). Your post
is about VB.Net. VB and VB.Net are entirely different, so a
VB answer would leave you even more confused. The winapi
group should be dropped from your postings.

For VB.Net you can also try the groups below, or any other
group with "dotnet" or "vsnet" in the name. If it doesn't
include "dotnet" then it's not .Net.

microsoft.public.dotnet.general
microsoft.public.dotnet.languages.vb
microsoft.public.vsnet.general

Sep 26 '08 #2
On 2008-09-26, Ketchup <ke*****@ketchup.comwrote:
This is a multi-part message in MIME format.

------=_NextPart_000_0006_01C91FB5.49F3B5E0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Hello everyone,

I have been stuck with this problem for quite some time now. I am =
working in VB.NET, using framework 1.0. I have to keep the =
compatibility down to the original .NET framework as much as possible. =
I am forced to use API calls for several functions, one of which is =
ReadFile. The reason is because the framework seems to use ANSI =
versions of all API functions, limiting the MAX_PATH for filenames to =
about 260 chars for everything in System.IO. API Wide functions =
(Unicode) do not have this limitation. =20
Sorry - but, the framework does use the Wide functions. Even the W functions,
do not allow paths greater the MAX_PATH (defined as 260), by default. To get
the full path support, you have to prefix the path with \\?\.

Unfortunately, you can't just do that in .NET - the framework doesn't allow
it. The main reason for that is that not all W functions actually honor the
\\?\ prefix.

I am having issues implementing the ReadFile function. I seem to only =
get various exceptions whenever I try to use it. It's declared as =
follows:

<DllImport("kernel32", EntryPoint:=3D"ReadFile", =
CharSet:=3DCharSet.Unicode, SetLastError:=3DTrue, _
ExactSpelling:=3DTrue, CallingConvention:=3DCallingConvention.StdCall)=
_
Shared Function ReadFile(ByVal hFile As Integer, ByRef lpBuffer As =
Object, _
ByVal nNumberOfBytesToRead As Integer, ByRef lpNumberOfBytesRead As =
Integer, _
ByRef lpOverlapped As OVERLAPPED) As Integer

End Function
Here is a simple example of using ReadFile:

Option Strict On
Option Explicit On

Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Text

Module Module1
Declare Auto Function ReadFile Lib "kernel32" ( _
ByVal hFile As IntPtr, _
ByVal lpBuffer() As Byte, _
ByVal nNumberOfBytesToRead As Integer, _
ByRef lpNumberOfBytesRead As Integer, _
ByVal lpOverLapped As IntPtr) As Integer

'#define GENERIC_READ (0x80000000L)
'#define GENERIC_WRITE (0x40000000L)
'#define GENERIC_EXECUTE (0x20000000L)
'#define GENERIC_ALL (0x10000000L)
<Flags()_
Enum DesiredAccess
Read = &H80000000
Write = &H40000000
Execute = &H20000000
All = &H10000000
End Enum

' 0 0x00000000
'FILE_SHARE_DELETE 0x00000004
'FILE_SHARE_READ 0x00000001
'FILE_SHARE_WRITE 0x00000002
<Flags()_
Enum ShareMode
None = 0
Read = &H1
Write = &H2
Delete = &H4
End Enum

Enum CreateMode
CreateNew = 1
CreateAlways = 2
OpenExisting = 3
OpenAlways = 4
TruncateExisting = 5
End Enum

' HANDLE WINAPI CreateFile(
' __in LPCTSTR lpFileName,
' __in DWORD dwDesiredAccess,
' __in DWORD dwShareMode,
' __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
' __in DWORD dwCreationDisposition,
' __in DWORD dwFlagsAndAttributes,
' __in_opt HANDLE hTemplateFile
');
Declare Auto Function CreateFile Lib "kernel32" ( _
ByVal lpFileName As String, _
ByVal dwDesiredAccess As DesiredAccess, _
ByVal dwShareMode As ShareMode, _
ByVal lpSecurityAttributes As IntPtr, _
ByVal dwCreationDisposition As CreateMode, _
ByVal dwFlagsAndAttributes As Integer, _
ByVal hTemplateFile As IntPtr) As IntPtr

Declare Function CloseHandle Lib "kernel32" (ByVal hObject As IntPtr) As Boolean

Sub Main()

Using f As StreamWriter = File.CreateText("testing.txt")
f.WriteLine("Hello, you little monkey you!")
End Using

Dim hFile As IntPtr = CreateFile("testing.txt", DesiredAccess.Read, ShareMode.None, IntPtr.Zero, CreateMode.OpenExisting, 0, IntPtr.Zero)

Dim buffer(256) As Byte
Dim count As Integer

ReadFile(hFile, buffer, buffer.Length, count, IntPtr.Zero)
Console.WriteLine(Encoding.Default.GetString(buffe r, 0, count))

CloseHandle(hFile)

End Sub
End Module

--
Tom Shelton
Sep 26 '08 #3

"mayayana" <ma********@rcXXn.comwrote in message
news:ed**************@TK2MSFTNGP02.phx.gbl...
>
This group (winapi) is for VB (mainly v. 5 and 6).
You new here?

Tom Dacon
Dacon Software Consulting
Sep 26 '08 #4
"Tom Dacon" <td****@community.nospamwrote in message
news:e5**************@TK2MSFTNGP05.phx.gbl...
>
"mayayana" <ma********@rcXXn.comwrote in message
news:ed**************@TK2MSFTNGP02.phx.gbl...
>>
This group (winapi) is for VB (mainly v. 5 and 6).

You new here?
More like the OP's new here. He's the one crossposting between languages.

--
Ken Halter
Part time groupie
Sep 26 '08 #5
Tom,

You are a genius! Switching the Object type to an array of Bytes and
passing it ByVal instead of ByRef worked like a charm.

Thank you!

dmitry

P.S. I didn't know that framework used W functions. It really would be
nice if MS expanded support to the 32k char MAX_PATH of NTFS.
"Tom Shelton" <to*********@comcastXXXXXXX.netwrote in message
news:Os******************************@comcast.com. ..
On 2008-09-26, Ketchup <ke*****@ketchup.comwrote:
>This is a multi-part message in MIME format.

------=_NextPart_000_0006_01C91FB5.49F3B5E0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Hello everyone,

I have been stuck with this problem for quite some time now. I am =
working in VB.NET, using framework 1.0. I have to keep the =
compatibility down to the original .NET framework as much as possible.
=
I am forced to use API calls for several functions, one of which is =
ReadFile. The reason is because the framework seems to use ANSI =
versions of all API functions, limiting the MAX_PATH for filenames to =
about 260 chars for everything in System.IO. API Wide functions =
(Unicode) do not have this limitation. =20

Sorry - but, the framework does use the Wide functions. Even the W
functions,
do not allow paths greater the MAX_PATH (defined as 260), by default. To
get
the full path support, you have to prefix the path with \\?\.

Unfortunately, you can't just do that in .NET - the framework doesn't
allow
it. The main reason for that is that not all W functions actually honor
the
\\?\ prefix.

>I am having issues implementing the ReadFile function. I seem to only
=
get various exceptions whenever I try to use it. It's declared as =
follows:

<DllImport("kernel32", EntryPoint:=3D"ReadFile", =
CharSet:=3DCharSet.Unicode, SetLastError:=3DTrue, _
ExactSpelling:=3DTrue, CallingConvention:=3DCallingConvention.StdCall)=
_
Shared Function ReadFile(ByVal hFile As Integer, ByRef lpBuffer As =
Object, _
ByVal nNumberOfBytesToRead As Integer, ByRef lpNumberOfBytesRead As =
Integer, _
ByRef lpOverlapped As OVERLAPPED) As Integer

End Function

Here is a simple example of using ReadFile:

Option Strict On
Option Explicit On

Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Text

Module Module1
Declare Auto Function ReadFile Lib "kernel32" ( _
ByVal hFile As IntPtr, _
ByVal lpBuffer() As Byte, _
ByVal nNumberOfBytesToRead As Integer, _
ByRef lpNumberOfBytesRead As Integer, _
ByVal lpOverLapped As IntPtr) As Integer

'#define GENERIC_READ (0x80000000L)
'#define GENERIC_WRITE (0x40000000L)
'#define GENERIC_EXECUTE (0x20000000L)
'#define GENERIC_ALL (0x10000000L)
<Flags()_
Enum DesiredAccess
Read = &H80000000
Write = &H40000000
Execute = &H20000000
All = &H10000000
End Enum

' 0 0x00000000
'FILE_SHARE_DELETE 0x00000004
'FILE_SHARE_READ 0x00000001
'FILE_SHARE_WRITE 0x00000002
<Flags()_
Enum ShareMode
None = 0
Read = &H1
Write = &H2
Delete = &H4
End Enum

Enum CreateMode
CreateNew = 1
CreateAlways = 2
OpenExisting = 3
OpenAlways = 4
TruncateExisting = 5
End Enum

' HANDLE WINAPI CreateFile(
' __in LPCTSTR lpFileName,
' __in DWORD dwDesiredAccess,
' __in DWORD dwShareMode,
' __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
' __in DWORD dwCreationDisposition,
' __in DWORD dwFlagsAndAttributes,
' __in_opt HANDLE hTemplateFile
');
Declare Auto Function CreateFile Lib "kernel32" ( _
ByVal lpFileName As String, _
ByVal dwDesiredAccess As DesiredAccess, _
ByVal dwShareMode As ShareMode, _
ByVal lpSecurityAttributes As IntPtr, _
ByVal dwCreationDisposition As CreateMode, _
ByVal dwFlagsAndAttributes As Integer, _
ByVal hTemplateFile As IntPtr) As IntPtr

Declare Function CloseHandle Lib "kernel32" (ByVal hObject As IntPtr)
As Boolean

Sub Main()

Using f As StreamWriter = File.CreateText("testing.txt")
f.WriteLine("Hello, you little monkey you!")
End Using

Dim hFile As IntPtr = CreateFile("testing.txt", DesiredAccess.Read,
ShareMode.None, IntPtr.Zero, CreateMode.OpenExisting, 0, IntPtr.Zero)

Dim buffer(256) As Byte
Dim count As Integer

ReadFile(hFile, buffer, buffer.Length, count, IntPtr.Zero)
Console.WriteLine(Encoding.Default.GetString(buffe r, 0, count))

CloseHandle(hFile)

End Sub
End Module

--
Tom Shelton

Sep 26 '08 #6
Ken,

We disagree, I find the crossposting from the OP complete correct when I
had read his question.
It could not have been better.

Luckily Tom could help him. I don't know from what newsgroup, as Tom is
active in more than one.

jmo

Cor

"Ken Halter" <Ken_Halter@Use_Sparingly_Hotmail.comschreef in bericht
news:ez**************@TK2MSFTNGP02.phx.gbl...
"Tom Dacon" <td****@community.nospamwrote in message
news:e5**************@TK2MSFTNGP05.phx.gbl...
>>
"mayayana" <ma********@rcXXn.comwrote in message
news:ed**************@TK2MSFTNGP02.phx.gbl...
>>>
This group (winapi) is for VB (mainly v. 5 and 6).

You new here?

More like the OP's new here. He's the one crossposting between languages.

--
Ken Halter
Part time groupie
Sep 26 '08 #7
"Ketchup" wrote:
...

P.S. I didn't know that framework used W functions. It really would be
nice if MS expanded support to the 32k char MAX_PATH of NTFS.
They would like to. Here is what they have been thinking.

http://blogs.msdn.com/bclteam/archiv...-hamilton.aspx

http://blogs.msdn.com/bclteam/archiv...-hamilton.aspx

http://blogs.msdn.com/bclteam/archiv...-hamilton.aspx

Regards,

David
Sep 26 '08 #8
David, thanks for the links. I hadn't realized that there are such issues
with the Windows API. I am guessing the MAX_PATH limitation is a throw
back to FAT file system days. In the computer forensics world, we can't
alter the original paths and must preserve all of the metadata. This is
why I am having to revert to API calls for most of my System.IO needs. At
this point, I am getting pretty comfortable with it and enjoying it as well
:)

The idea of moving away from string paths is interesting, as long as we will
still be able to produce a report with string paths that exceed the 260 char
limit. I guess I will wait an see.

thanks again!

"David Thompson" <jw***@community.nospamwrote in message
news:DD**********************************@microsof t.com...
"Ketchup" wrote:
>...

P.S. I didn't know that framework used W functions. It really would be
nice if MS expanded support to the 32k char MAX_PATH of NTFS.

They would like to. Here is what they have been thinking.

http://blogs.msdn.com/bclteam/archiv...-hamilton.aspx

http://blogs.msdn.com/bclteam/archiv...-hamilton.aspx

http://blogs.msdn.com/bclteam/archiv...-hamilton.aspx

Regards,

David

Sep 26 '08 #9
On 2008-09-26, Ketchup <ke*****@ketchup.comwrote:
David, thanks for the links. I hadn't realized that there are such issues
with the Windows API. I am guessing the MAX_PATH limitation is a throw
back to FAT file system days. In the computer forensics world, we can't
alter the original paths and must preserve all of the metadata. This is
why I am having to revert to API calls for most of my System.IO needs. At
this point, I am getting pretty comfortable with it and enjoying it as well
:)

The idea of moving away from string paths is interesting, as long as we will
still be able to produce a report with string paths that exceed the 260 char
limit. I guess I will wait an see.

thanks again!
Not sure if you caught it or not - but, from the information in those links,
you should be able to avoid the ReadFile calls. The trick is to simply use
CreateFile to open the file, and then create your stream from the file handle
returned. Here is my example reworked to eliminate the ReadFile and has the
\\?\ - it seems when you do this you must use the fully qualified names:

Option Strict On
Option Explicit On

Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Text
Imports Microsoft.Win32.SafeHandles

Module Module1
'#define GENERIC_READ (0x80000000L)
'#define GENERIC_WRITE (0x40000000L)
'#define GENERIC_EXECUTE (0x20000000L)
'#define GENERIC_ALL (0x10000000L)
<Flags()_
Enum DesiredAccess
Read = &H80000000
Write = &H40000000
Execute = &H20000000
All = &H10000000
End Enum

' 0 0x00000000
'FILE_SHARE_DELETE 0x00000004
'FILE_SHARE_READ 0x00000001
'FILE_SHARE_WRITE 0x00000002
<Flags()_
Enum ShareMode
None = 0
Read = &H1
Write = &H2
Delete = &H4
End Enum

Enum CreateMode
CreateNew = 1
CreateAlways = 2
OpenExisting = 3
OpenAlways = 4
TruncateExisting = 5
End Enum

' HANDLE WINAPI CreateFile(
' __in LPCTSTR lpFileName,
' __in DWORD dwDesiredAccess,
' __in DWORD dwShareMode,
' __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
' __in DWORD dwCreationDisposition,
' __in DWORD dwFlagsAndAttributes,
' __in_opt HANDLE hTemplateFile
');
Declare Auto Function CreateFile Lib "kernel32" ( _
ByVal lpFileName As String, _
ByVal dwDesiredAccess As DesiredAccess, _
ByVal dwShareMode As ShareMode, _
ByVal lpSecurityAttributes As IntPtr, _
ByVal dwCreationDisposition As CreateMode, _
ByVal dwFlagsAndAttributes As Integer, _
ByVal hTemplateFile As IntPtr) As SafeFileHandle

Sub Main()

Dim hFile As SafeFileHandle = CreateFile( _
"\\?\c:\testing.txt", _
DesiredAccess.Write, _
ShareMode.None, _
IntPtr.Zero, _
CreateMode.CreateAlways, _
0, _
IntPtr.Zero)

Using f As StreamWriter = New StreamWriter(New FileStream(hFile, FileAccess.Write))
f.WriteLine("Hello, you little monkey you!")
End Using

hFile = CreateFile( _
"\\?\c:\testing.txt", _
DesiredAccess.Read, _
ShareMode.None, _
IntPtr.Zero, _
CreateMode.OpenExisting, _
0, _
IntPtr.Zero)

Using reader As New StreamReader(New FileStream(hFile, FileAccess.Read))
Console.WriteLine(reader.ReadToEnd())
End Using

End Sub
End Module

The nice thing about using the SafeFileHandle - is that you can check to see
if CreateFile returned an INVALID_HANDLE, like this:

If Not hFile.IsInvalid Then
' do cool stuff with file handle
Else
Throw New Win32Exception (Marshal.GetLastWin32Error())
End If

Thanks for asking this question! Now, I'll know what I'm doing if this ever
comes up for me :)

--
Tom Shelton
Sep 26 '08 #10
We disagree, I find the crossposting from the OP complete correct when I
had read his question.
It could not have been better.
microsoft.public.dotnet.languages.vb is fine
but the group microsoft.public.vb.winapi is a VB
(VB6 and lower) group. It doesn't matter that
it's an API question. VB and VB.Net are different
where the API is concerned, just as they're
different in other aspects. You're a regular on
the .Net groups. You should know which groups
are .Net and which are not.
Sep 27 '08 #11
Tom, thank you again. I saw that at first, but I was so excited to get
ReadFile working, that I didn't even give a try. After looking at your
example, I see the benefits of doing it the way you suggested. One issue
I have is that SafeHandle seems to be introduced in framework 2.0. I am
working in 1.0. That shouldn't stop this approach from working however.
I should be able to use IntPtr as a handle to the file. There are 9
versions of the constructor for FileStream, several of which accept a IntPtr
for the handle.

I think that I will rewrite my code to use the System.IO.FileStream classes.
Error handling is much easier with the framework.

thanks again!

"Tom Shelton" <to*********@comcastXXXXXXX.netwrote in message
news:OI******************************@comcast.com. ..
On 2008-09-26, Ketchup <ke*****@ketchup.comwrote:
Not sure if you caught it or not - but, from the information in those
links,
you should be able to avoid the ReadFile calls. The trick is to simply
use
CreateFile to open the file, and then create your stream from the file
handle
returned. Here is my example reworked to eliminate the ReadFile and has
the
\\?\ - it seems when you do this you must use the fully qualified names:

Option Strict On
Option Explicit On

Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Text
Imports Microsoft.Win32.SafeHandles

Module Module1
'#define GENERIC_READ (0x80000000L)
'#define GENERIC_WRITE (0x40000000L)
'#define GENERIC_EXECUTE (0x20000000L)
'#define GENERIC_ALL (0x10000000L)
<Flags()_
Enum DesiredAccess
Read = &H80000000
Write = &H40000000
Execute = &H20000000
All = &H10000000
End Enum

' 0 0x00000000
'FILE_SHARE_DELETE 0x00000004
'FILE_SHARE_READ 0x00000001
'FILE_SHARE_WRITE 0x00000002
<Flags()_
Enum ShareMode
None = 0
Read = &H1
Write = &H2
Delete = &H4
End Enum

Enum CreateMode
CreateNew = 1
CreateAlways = 2
OpenExisting = 3
OpenAlways = 4
TruncateExisting = 5
End Enum

' HANDLE WINAPI CreateFile(
' __in LPCTSTR lpFileName,
' __in DWORD dwDesiredAccess,
' __in DWORD dwShareMode,
' __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
' __in DWORD dwCreationDisposition,
' __in DWORD dwFlagsAndAttributes,
' __in_opt HANDLE hTemplateFile
');
Declare Auto Function CreateFile Lib "kernel32" ( _
ByVal lpFileName As String, _
ByVal dwDesiredAccess As DesiredAccess, _
ByVal dwShareMode As ShareMode, _
ByVal lpSecurityAttributes As IntPtr, _
ByVal dwCreationDisposition As CreateMode, _
ByVal dwFlagsAndAttributes As Integer, _
ByVal hTemplateFile As IntPtr) As SafeFileHandle

Sub Main()

Dim hFile As SafeFileHandle = CreateFile( _
"\\?\c:\testing.txt", _
DesiredAccess.Write, _
ShareMode.None, _
IntPtr.Zero, _
CreateMode.CreateAlways, _
0, _
IntPtr.Zero)

Using f As StreamWriter = New StreamWriter(New FileStream(hFile,
FileAccess.Write))
f.WriteLine("Hello, you little monkey you!")
End Using

hFile = CreateFile( _
"\\?\c:\testing.txt", _
DesiredAccess.Read, _
ShareMode.None, _
IntPtr.Zero, _
CreateMode.OpenExisting, _
0, _
IntPtr.Zero)

Using reader As New StreamReader(New FileStream(hFile,
FileAccess.Read))
Console.WriteLine(reader.ReadToEnd())
End Using

End Sub
End Module

The nice thing about using the SafeFileHandle - is that you can check to
see
if CreateFile returned an INVALID_HANDLE, like this:

If Not hFile.IsInvalid Then
' do cool stuff with file handle
Else
Throw New Win32Exception (Marshal.GetLastWin32Error())
End If

Thanks for asking this question! Now, I'll know what I'm doing if this
ever
comes up for me :)

--
Tom Shelton

Sep 27 '08 #12
Yep, it works with a plain IntPtr! Excellent. Thanks everyone!

"Ketchup" <ke*****@ketchup.comwrote in message
news:Or**************@TK2MSFTNGP04.phx.gbl...
Tom, thank you again. I saw that at first, but I was so excited to get
ReadFile working, that I didn't even give a try. After looking at your
example, I see the benefits of doing it the way you suggested. One
issue I have is that SafeHandle seems to be introduced in framework 2.0.
I am working in 1.0. That shouldn't stop this approach from working
however. I should be able to use IntPtr as a handle to the file. There
are 9 versions of the constructor for FileStream, several of which accept
a IntPtr for the handle.

I think that I will rewrite my code to use the System.IO.FileStream
classes. Error handling is much easier with the framework.

thanks again!

"Tom Shelton" <to*********@comcastXXXXXXX.netwrote in message
news:OI******************************@comcast.com. ..
>On 2008-09-26, Ketchup <ke*****@ketchup.comwrote:
>Not sure if you caught it or not - but, from the information in those
links,
you should be able to avoid the ReadFile calls. The trick is to simply
use
CreateFile to open the file, and then create your stream from the file
handle
returned. Here is my example reworked to eliminate the ReadFile and has
the
\\?\ - it seems when you do this you must use the fully qualified names:

Option Strict On
Option Explicit On

Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Text
Imports Microsoft.Win32.SafeHandles

Module Module1
'#define GENERIC_READ (0x80000000L)
'#define GENERIC_WRITE (0x40000000L)
'#define GENERIC_EXECUTE (0x20000000L)
'#define GENERIC_ALL (0x10000000L)
<Flags()_
Enum DesiredAccess
Read = &H80000000
Write = &H40000000
Execute = &H20000000
All = &H10000000
End Enum

' 0 0x00000000
'FILE_SHARE_DELETE 0x00000004
'FILE_SHARE_READ 0x00000001
'FILE_SHARE_WRITE 0x00000002
<Flags()_
Enum ShareMode
None = 0
Read = &H1
Write = &H2
Delete = &H4
End Enum

Enum CreateMode
CreateNew = 1
CreateAlways = 2
OpenExisting = 3
OpenAlways = 4
TruncateExisting = 5
End Enum

' HANDLE WINAPI CreateFile(
' __in LPCTSTR lpFileName,
' __in DWORD dwDesiredAccess,
' __in DWORD dwShareMode,
' __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
' __in DWORD dwCreationDisposition,
' __in DWORD dwFlagsAndAttributes,
' __in_opt HANDLE hTemplateFile
');
Declare Auto Function CreateFile Lib "kernel32" ( _
ByVal lpFileName As String, _
ByVal dwDesiredAccess As DesiredAccess, _
ByVal dwShareMode As ShareMode, _
ByVal lpSecurityAttributes As IntPtr, _
ByVal dwCreationDisposition As CreateMode, _
ByVal dwFlagsAndAttributes As Integer, _
ByVal hTemplateFile As IntPtr) As SafeFileHandle

Sub Main()

Dim hFile As SafeFileHandle = CreateFile( _
"\\?\c:\testing.txt", _
DesiredAccess.Write, _
ShareMode.None, _
IntPtr.Zero, _
CreateMode.CreateAlways, _
0, _
IntPtr.Zero)

Using f As StreamWriter = New StreamWriter(New FileStream(hFile,
FileAccess.Write))
f.WriteLine("Hello, you little monkey you!")
End Using

hFile = CreateFile( _
"\\?\c:\testing.txt", _
DesiredAccess.Read, _
ShareMode.None, _
IntPtr.Zero, _
CreateMode.OpenExisting, _
0, _
IntPtr.Zero)

Using reader As New StreamReader(New FileStream(hFile,
FileAccess.Read))
Console.WriteLine(reader.ReadToEnd())
End Using

End Sub
End Module

The nice thing about using the SafeFileHandle - is that you can check to
see
if CreateFile returned an INVALID_HANDLE, like this:

If Not hFile.IsInvalid Then
' do cool stuff with file handle
Else
Throw New Win32Exception (Marshal.GetLastWin32Error())
End If

Thanks for asking this question! Now, I'll know what I'm doing if this
ever
comes up for me :)

--
Tom Shelton


Sep 27 '08 #13
Cor Ligthert[MVP] <no************@planet.nlschrieb im Beitrag
<9A**********************************@microsoft.co m>...
We disagree, I find the crossposting from the OP complete correct when I
had read his question.
It could not have been better.

Luckily Tom could help him. I don't know from what newsgroup, as Tom is
active in more than one.
As far as I can see Tom knows it better and has removed
microsoft.public.vb.winapi from the list of recipients of the answer which
seem to talk about. The only posting from Tom which made its way through to
m.p.vb.winapi is his "You new here?" question...

--
----------------------------------------------------------------------
Thorsten Albers albers(a)uni-freiburg.de
----------------------------------------------------------------------

Sep 27 '08 #14
Yea I am sure that Tom knows,

However why should Ketchup knows it, not everybody is as good as you.

Bye

Cor

"Thorsten Albers" <al******@MOVEuni-freiburg.deschreef in bericht
news:01c920b4$155899e0$af01a8c0@Router...
Cor Ligthert[MVP] <no************@planet.nlschrieb im Beitrag
<9A**********************************@microsoft.co m>...
>We disagree, I find the crossposting from the OP complete correct when I
>had read his question.
It could not have been better.

Luckily Tom could help him. I don't know from what newsgroup, as Tom is
active in more than one.

As far as I can see Tom knows it better and has removed
microsoft.public.vb.winapi from the list of recipients of the answer which
seem to talk about. The only posting from Tom which made its way through
to
m.p.vb.winapi is his "You new here?" question...

--
----------------------------------------------------------------------
Thorsten Albers albers(a)uni-freiburg.de
----------------------------------------------------------------------
Sep 27 '08 #15
On 2008-09-27, Ketchup <ke*****@ketchup.comwrote:
Yep, it works with a plain IntPtr! Excellent. Thanks everyone!
Nice.

--
Tom Shelton
Sep 27 '08 #16

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

7 posts views Thread by Pablo J Royo | last post: by
2 posts views Thread by collinm | last post: by
1 post views Thread by Jørn Dahl-Stamnes | last post: by
4 posts views Thread by Eric Renken | last post: by
12 posts views Thread by salonowiec | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by Mortomer39 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.