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

C#, CreateFile and FileStream = Invalid Handler

477 views
Skip to first unread message

Adam W

unread,
Oct 2, 2005, 2:17:40 AM10/2/05
to
Hi Gurus,

I've been playing with this C# code for 2 days and Googling like a Mad
Code Monkey. I hope you can help.

I'm working on a program that can read and write bits on the Floppy
Drive (A). The overall goal is to read/write blocks (512 bytes).
However, my CreateFile function is bringing back a -1, Invalid Handler.
Therefore, when I pass it open a FileStream, all heck breaks loose.

I'm Using:

using System;
using System.IO;
using System.Runtime.InteropServices;

I've also brought in:

[DllImport("Kernel32.dll")]
static extern IntPtr CreateFile(string filename,
[MarshalAs(UnmanagedType.U4)]FileAccess fileaccess,
[MarshalAs(UnmanagedType.U4)]FileShare fileshare,
int securityattributes,
[MarshalAs(UnmanagedType.U4)]FileMode creationdisposition,
int flags,
IntPtr template);
static int FILE_FLAG_NO_BUFFERING = 0x20000000;

Now for the Code:

public void test()
{
IntPtr ptr = CreateFile("\\\\.\\A:",
FileAccess.ReadWrite,
FileShare.ReadWrite,
0,
FileMode.OpenOrCreate,
FILE_FLAG_NO_BUFFERING,
IntPtr.Zero);

FileStream disk = new FileStream(ptr, FileAccess.ReadWrite);

byte[] outBuffer = new byte[512];
byte[] inBuffer = new byte[512];

outBuffer[0] = 1;
outBuffer[1] = 0;
outBuffer[2] = 1;

disk.Seek(0, SeekOrigin.Begin);
for (int i=0; i<512; i++)
{
disk.WriteByte(outBuffer[i]);
}

disk.Seek(0, SeekOrigin.Begin);
for (int i=0; i<512; i++)
{
inBuffer[i] = (byte) disk.ReadByte();
}
for (int i=0; i<20; i++)
{
Console.Write(inBuffer[i]);
}
Console.WriteLine();

}

I really like C#. I can make this work in C++, but I really don't want
to port the rest over. Thanks so much for your help.

Adam

Egbert Nierop (MVP for IIS)

unread,
Oct 2, 2005, 6:50:44 AM10/2/05
to

"Adam W" <adamwo...@gmail.com> wrote in message
news:1128233860.4...@g43g2000cwa.googlegroups.com...

> Hi Gurus,
>
> I've been playing with this C# code for 2 days and Googling like a Mad
> Code Monkey. I hope you can help.
>
> I'm working on a program that can read and write bits on the Floppy
> Drive (A). The overall goal is to read/write blocks (512 bytes).
> However, my CreateFile function is bringing back a -1, Invalid Handler.
> Therefore, when I pass it open a FileStream, all heck breaks loose.

> I'm Using:
>
> using System;
> using System.IO;
> using System.Runtime.InteropServices;
>
> I've also brought in:
>
> [DllImport("Kernel32.dll")]
> static extern IntPtr CreateFile(string filename,
> [MarshalAs(UnmanagedType.U4)]FileAccess fileaccess,


euh, what makes you thinkm that the FileAccess enum, is compatible with the
flags that are given for The win32 equivalent?
I might be wrong, but I am very suspicious about this.

Success

Adam W

unread,
Oct 2, 2005, 2:10:07 PM10/2/05
to
I've tried various snippets of code for CreateFile, each one yielding
the same result. Would you have a better code recommendation?

Thanks. I really appreciate the help.

Adam

Willy Denoyette [MVP]

unread,
Oct 2, 2005, 3:13:52 PM10/2/05
to
Works for me.
Are you sure a floppy is mounted?

Willy.


"Adam W" <adamwo...@gmail.com> wrote in message
news:1128233860.4...@g43g2000cwa.googlegroups.com...

Willy Denoyette [MVP]

unread,
Oct 2, 2005, 3:14:49 PM10/2/05
to

"Egbert Nierop (MVP for IIS)" <egbert...@nospam.invalid> wrote in
message news:Or7sm8zx...@TK2MSFTNGP14.phx.gbl...

>
> "Adam W" <adamwo...@gmail.com> wrote in message
> news:1128233860.4...@g43g2000cwa.googlegroups.com...
>> Hi Gurus,
>>
>> I've been playing with this C# code for 2 days and Googling like a Mad
>> Code Monkey. I hope you can help.
>>
>> I'm working on a program that can read and write bits on the Floppy
>> Drive (A). The overall goal is to read/write blocks (512 bytes).
>> However, my CreateFile function is bringing back a -1, Invalid Handler.
>> Therefore, when I pass it open a FileStream, all heck breaks loose.
>
>> I'm Using:
>>
>> using System;
>> using System.IO;
>> using System.Runtime.InteropServices;
>>
>> I've also brought in:
>>
>> [DllImport("Kernel32.dll")]
>> static extern IntPtr CreateFile(string filename,
>> [MarshalAs(UnmanagedType.U4)]FileAccess fileaccess,
>
>
> euh, what makes you thinkm that the FileAccess enum, is compatible with
> the flags that are given for The win32 equivalent?
> I might be wrong, but I am very suspicious about this.

No need to, they are compatible.

Willy.


Adam W

unread,
Oct 2, 2005, 3:19:37 PM10/2/05
to
Okay, I've updated my code:

[Flags]
public enum EFileAccess : uint
{
GenericRead = 0x80000000,
GenericWrite = 0x40000000,
GenericExecute = 0x20000000,
GenericAll = 0x10000000,
}

[Flags]
public enum EFileShare : uint
{
None = 0x00000000,
Read = 0x00000001,
Write = 0x00000002,
Delete = 0x00000004,
}

public enum ECreationDisposition : uint
{
New = 1,
CreateAlways = 2,
OpenExisting = 3,
OpenAlways = 4,
TruncateExisting = 5,
}

[Flags]
public enum EFileAttributes : uint
{
Readonly = 0x00000001,
Hidden = 0x00000002,
System = 0x00000004,
Directory = 0x00000010,
Archive = 0x00000020,
Device = 0x00000040,
Normal = 0x00000080,
Temporary = 0x00000100,
SparseFile = 0x00000200,
ReparsePoint = 0x00000400,
Compressed = 0x00000800,
Offline = 0x00001000,
NotContentIndexed = 0x00002000,
Encrypted = 0x00004000,
Write_Through = 0x80000000,
Overlapped = 0x40000000,
NoBuffering = 0x20000000,
RandomAccess = 0x10000000,
SequentialScan = 0x08000000,
DeleteOnClose = 0x04000000,
BackupSemantics = 0x02000000,
PosixSemantics = 0x01000000,
OpenReparsePoint = 0x00200000,
OpenNoRecall = 0x00100000,
FirstPipeInstance = 0x00080000
}

[DllImport("kernel32", SetLastError=true)]
static extern unsafe IntPtr CreateFile(
string FileName, // file name
uint DesiredAccess, // access mode
uint ShareMode, // share mode
uint SecurityAttributes, // Security Attributes
uint CreationDisposition, // how to create
uint FlagsAndAttributes, // file attributes
int hTemplateFile); // handle to template file

public void Test3()
{

IntPtr handle = CreateFile(@"\\\\.\\A:",
(uint) (EFileAccess.GenericRead | EFileAccess.GenericWrite),
(uint) (EFileShare.Read | EFileShare.Write),
0,
(uint) (ECreationDisposition.OpenExisting),
(uint) (EFileAttributes.NoBuffering),
(int) IntPtr.Zero);
if (handle.ToInt32() == -1)
{
Console.WriteLine("Invalid Handle: " + handle);
}
else
{
Console.WriteLine("Handle: " + handle);

FileStream disk = new FileStream(handle,
FileAccess.ReadWrite);

byte[] outBuffer = new byte[512];
byte[] inBuffer = new byte[512];
outBuffer[0] = 1;
outBuffer[1] = 0;
outBuffer[2] = 1;

disk.Seek(0, SeekOrigin.Begin);

for (int i=0; i<512; i++)
{
disk.WriteByte(outBuffer[i]);
}

disk.Seek(0, SeekOrigin.Begin);

for (int i=0; i<512; i++)
{
inBuffer[i] = (byte) disk.ReadByte();
}

for (int i=0; i<20; i++)
{
Console.Write(inBuffer[i]);
}
Console.WriteLine();
}
}

Now when I take the @ out of @"\\\\.\\A:", it returns a handle of 336,
but then when I call FileStream, I get an IOException: Incorrect
Function. If I have the @ symbol, I get the Invalid Handler exception.

Thanks for your continued help.

Adam

Adam W

unread,
Oct 2, 2005, 4:18:15 PM10/2/05
to
I'm running Windows XP pro. If mounted means, "is the floppy in the
drive and is it marked as the a drive and can you access disk from
windows?", then yes. However, if there are extra steps for mounting a
floppy, I don't know about them.

Egbert Nierop (MVP for IIS)

unread,
Oct 3, 2005, 2:52:38 AM10/3/05
to

"Adam W" <adamwo...@gmail.com> wrote in message
news:1128284295.3...@f14g2000cwb.googlegroups.com...

If it works for Adam ( I did not try since I don't have floppies in my
company!) could an anti-virustool block it? Do you have a BIOS readonly
setting? Just guessing wild :)

Egbert Nierop (MVP for IIS)

unread,
Oct 3, 2005, 7:08:27 AM10/3/05
to

"Adam W" <adamwo...@gmail.com> wrote in message
news:1128284295.3...@f14g2000cwb.googlegroups.com...

If it works for Willy ( I did not try since I don't have floppies in my

Willy Denoyette [MVP]

unread,
Oct 3, 2005, 11:32:36 AM10/3/05
to

"Adam W" <adamwo...@gmail.com> wrote in message
news:1128284295.3...@f14g2000cwb.googlegroups.com...

No, what you need is a formatted floppy disk in the drive.
Now, what you are doing in your code works only once because you destroy
sector 0 by over-writing it. That means that this works only once, after
that you have to re-format the floppy disk.

So I changed your code into...

IntPtr InvalidHandle = new IntPtr(-1);


IntPtr ptr = CreateFile("\\\\.\\A:",
FileAccess.ReadWrite,
FileShare.ReadWrite,
0,
FileMode.OpenOrCreate,
FILE_FLAG_NO_BUFFERING,
IntPtr.Zero);

if (ptr == InvalidHandle)
{


FileStream disk = new FileStream(ptr, FileAccess.ReadWrite);

byte[] inBuffer = new byte[512];

disk.Seek(0, SeekOrigin.Begin);
for (int i=0; i<512; i++)
inBuffer[i] = (byte) disk.ReadByte();
for (int i=0; i<20; i++)
Console.Write(inBuffer[i]);
Console.WriteLine();
}

output: 235601447783687983534648021102224064

I initially tested this with v2.0 of the framework, were it works all the
time.
I also tried this on v1.1 and noticed that it ain't working at all, the
FileStream constructor throws a System.IO.IOException: The parameter is
incorrect.
Worse, the format of the floppy is destroyed after the run and you have to
re-format. This is clearly a bug in v1.1 of the framework.

Willy.

0 new messages