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

PInvoke of WriteFile from C#

691 views
Skip to first unread message

Gnanavel S

unread,
May 27, 2003, 9:20:22 AM5/27/03
to
Hi All,

I have a FileAccessor utiltiy class with which, I am trying to use Win32
calls to create a file and write some binary data inot the file.

In the FileAccessor class I have

[DllImport("kernel32", SetLastError=true)]
static extern unsafe int CreateFile(
string filename,
uint desiredAccess,
uint shareMode,
uint attributes,
uint creationDisposition,
uint flagsAndAttributes,
uint templateFile);

[DllImport("kernel32", SetLastError=true)]
static extern unsafe int WriteFile(
int hFile, void* lpBuffer,
int nBytesToWrite, out int nBytesWritten, int overlapped);

The way, I am creating the file is
int handle = CreateFile(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, 0,
CREATE_ALWAYS, 0, 0);

...

and I am tring to put some binary data into the file like ....
fixed (byte* bytePointer = buffer) {
int error = WriteFile(handle, (void *)(bytePointer + offset), length, out
actual, 0);
if(error == 0 || error == -1){
int errorCode = Marshal.GetLastWin32Error();
// I am repetedly getting always the error ERROR_INVALID_USER_BUFFER only
some times I do not get the error
}

Let me know what the problem is. Should we have to take care of anything
explicit for C#/.Net environment ?

Regards
Gnan

Bill Priess

unread,
May 27, 2003, 11:54:37 AM5/27/03
to
Hello Gnan,

IMHO, you should not have to use any Win32 API calls for File IO. The
System.IO namespace handles everything natively in the .NET environment and,
although sometimes cryptic, is overly packed with every method that you need
to open a file, write binary data to it, and close it again. You should have
a look at it and see if you can modify your code to use the System.IO
namespace.

For your FileAccessor class:

using System.IO;

static bool CreateFile(string FileName, int Buffer, byte[] Data)
{
BinaryWriter oWriter = new BinaryWriter(File.Create(FileName,
Buffer),System.Text.Encoding.UTF8);
oWriter.Write(Data);
oWriter.Close();
}

HTH,
Bill P.

"Gnanavel S" <gn...@best.ms.philips.com> wrote in message
news:3ed36538$0$1141$4d4e...@read-nat.news.nl.uu.net...

Brian Grunkemeyer [MS]

unread,
Jun 5, 2003, 7:56:10 PM6/5/03
to
Just to reiterate, please try to learn & use classes from our existing IO
namespace if possible. While I wasn't able to find the reason why your code
wasn't working after looking at this for about a minute, I did see at least
two 64 bit portability problems and two subtle lurking security bugs I fixed
in FileStream in V1 or V1.1. Plus, this code will not be reliable in future
versions of the CLR. If you can use FileStream, please do so. Using
P/Invoke to duplicate parts of the Framework is just asking for future pain.
I know the docs weren't great, but in V1.1 they should be better with many
more samples.

FYI - the best way to write a byte[] to a file is like this:

using(FileStream fs = File.Create(fileName)) {
fs.Write(buffer, 0, buffer.Length);
}

Note the C# using statement here automatically calls Dispose for you in a
try/finally block, closing the file handle even if Write failed. In a
future version, we may add a method like WriteAll(String fileName, byte[]
bytes) on File to make this easier to approach.

--
Brian Grunkemeyer
MS CLR Base Class Library team

This posting is provided "AS IS" with no warranties, and confers no rights.


"Bill Priess" <no....@nospam.com> wrote in message
news:egDRAhGJ...@tk2msftngp13.phx.gbl...

no potted meat@hotmail.com David Browne

unread,
Jun 6, 2003, 7:00:25 PM6/6/03
to
"Brian Grunkemeyer [MS]" <bria...@online.microsoft.com> wrote in message
news:%23lRXL47...@TK2MSFTNGP10.phx.gbl...

> Just to reiterate, please try to learn & use classes from our existing IO
> namespace if possible. While I wasn't able to find the reason why your
code
> wasn't working after looking at this for about a minute, I did see at
least
> two 64 bit portability problems and two subtle lurking security bugs I
fixed
> in FileStream in V1 or V1.1. Plus, this code will not be reliable in
future
> versions of the CLR. If you can use FileStream, please do so. Using
> P/Invoke to duplicate parts of the Framework is just asking for future
pain.
> I know the docs weren't great, but in V1.1 they should be better with many
> more samples.
>
> FYI - the best way to write a byte[] to a file is like this:
>
> using(FileStream fs = File.Create(fileName)) {
> fs.Write(buffer, 0, buffer.Length);
> }
>
> Note the C# using statement here automatically calls Dispose for you in a
> try/finally block, closing the file handle even if Write failed. In a
> future version, we may add a method like WriteAll(String fileName, byte[]
> bytes) on File to make this easier to approach.
>
> --
> Brian Grunkemeyer
> MS CLR Base Class Library team
>

I have implemented an ExtendedFileStream subclass of FileStream to get
access to alternate file streams and temporary files using
FILE_FLAG_TEMPORARY, FILE_FLAG_DELETE_ON_CLOSE.

ExtendedFileStream's constructor uses CreateFile though PInvoke, and passes
the handle to the IntPtr constructor for FileStream.

It seems to work for Named Pipes too, and I was thinking of using it for COM
ports as well.

Is this a good approach, or should I avoid the FileStream for accessing the
other OS objects which use file handles?

David


0 new messages