473,387 Members | 1,574 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Ridicilous!

<rant warning="I'm pissed off and have to vent" request="need help>
For the last couple of hours I'm struggling with a very *annoying* problem.
How to check if a user has a write access to a file?
Considerring that .Net is supposed to be a system for writing applications
for servers & clients, which in both cases has may have multi-users, I'm
amazed that this is not possible in the framework.
Initially I looked for something like:

System.IO.File.Access(string Filename, PermissionAccess);

Nothing!

Then I thought about System.Security.Permissions, and there is was, clear as
day FileIOPermission a class which "Controls the ability to access files
and folders."
But no! FileIOPermission works for .Net permissions, it doesn't do Win32
permissions!

Considerring that the framework is supposed to run on server class
platforms, why the omission?

In C & C++ I can do _access() and get the info I want, in .Net? I get to
delve into:

A> Interop code.
B> Win32 Security.

I can handle Interop if I absolutely have to, but even on a good day, using
C++ I don't like Win32 Security, and all the tricks that are used there.
I checked ACLs in .Net
http://www.gotdotnet.com/community/u...f-e0705af065d9
No go, it requires me to add a component that is bigger then my code just to
do so, and add several level of complexities to my life.
Not to mention, again, having to deal with all the minor details of Win32
security.

To remind you, I'm trying to find out if my code has write access to a file,
on a framework that support multiply users, networks and such, this should
be a snap.
Instead...

Opening a file and catching the exception is the only easy way that I've,
and that is *not acceptable*.
</rant>

Seriously now, I really need a way to solve this problem, preferably with
something like:
FileAccess.Verify(filename,WriteAccess);

Thanks in advance,
Ayende Rahien
Nov 16 '05 #1
26 1019
Ayende,

Unfortunately, the .NET Framework does not contain this functionality, and
calling into the Win32 API functions directly is quite a PITA. Luckily,
there is a managed wrapper available at
http://www.gotdotnet.com/Community/U...f-e0705af065d9.

HTH,
Nicole

"Ayende Rahien" <Ay****@no.spam> wrote in message
news:O3****************@TK2MSFTNGP12.phx.gbl...
<rant warning="I'm pissed off and have to vent" request="need help>
For the last couple of hours I'm struggling with a very *annoying*
problem.
How to check if a user has a write access to a file?
Considerring that .Net is supposed to be a system for writing applications
for servers & clients, which in both cases has may have multi-users, I'm
amazed that this is not possible in the framework.
Initially I looked for something like:

System.IO.File.Access(string Filename, PermissionAccess);

Nothing!

Then I thought about System.Security.Permissions, and there is was, clear
as
day FileIOPermission a class which "Controls the ability to access files
and folders."
But no! FileIOPermission works for .Net permissions, it doesn't do Win32
permissions!

Considerring that the framework is supposed to run on server class
platforms, why the omission?

In C & C++ I can do _access() and get the info I want, in .Net? I get to
delve into:

A> Interop code.
B> Win32 Security.

I can handle Interop if I absolutely have to, but even on a good day,
using
C++ I don't like Win32 Security, and all the tricks that are used there.
I checked ACLs in .Net
http://www.gotdotnet.com/community/u...f-e0705af065d9
No go, it requires me to add a component that is bigger then my code just
to
do so, and add several level of complexities to my life.
Not to mention, again, having to deal with all the minor details of Win32
security.

To remind you, I'm trying to find out if my code has write access to a
file,
on a framework that support multiply users, networks and such, this should
be a snap.
Instead...

Opening a file and catching the exception is the only easy way that I've,
and that is *not acceptable*.
</rant>

Seriously now, I really need a way to solve this problem, preferably with
something like:
FileAccess.Verify(filename,WriteAccess);

Thanks in advance,
Ayende Rahien

Nov 16 '05 #2
Yeah, I've seen that (see my original post), my problem is that my code
is a utility class, which can't have another library attached to it.
Beyond that, I could not fathom an easy way to see if I've an access to
a file.

Nicole Calinoiu wrote:
Ayende,

Unfortunately, the .NET Framework does not contain this functionality, and
calling into the Win32 API functions directly is quite a PITA. Luckily,
there is a managed wrapper available at
http://www.gotdotnet.com/Community/U...f-e0705af065d9.

HTH,
Nicole

"Ayende Rahien" <Ay****@no.spam> wrote in message
news:O3****************@TK2MSFTNGP12.phx.gbl...
<rant warning="I'm pissed off and have to vent" request="need help>
For the last couple of hours I'm struggling with a very *annoying*
problem.
How to check if a user has a write access to a file?
Considerring that .Net is supposed to be a system for writing applications
for servers & clients, which in both cases has may have multi-users, I'm
amazed that this is not possible in the framework.
Initially I looked for something like:

System.IO.File.Access(string Filename, PermissionAccess);

Nothing!

Then I thought about System.Security.Permissions, and there is was, clear
as
day FileIOPermission a class which "Controls the ability to access files
and folders."
But no! FileIOPermission works for .Net permissions, it doesn't do Win32
permissions!

Considerring that the framework is supposed to run on server class
platforms, why the omission?

In C & C++ I can do _access() and get the info I want, in .Net? I get to
delve into:

A> Interop code.
B> Win32 Security.

I can handle Interop if I absolutely have to, but even on a good day,
using
C++ I don't like Win32 Security, and all the tricks that are used there.
I checked ACLs in .Net
http://www.gotdotnet.com/community/u...f-e0705af065d9
No go, it requires me to add a component that is bigger then my code just
to
do so, and add several level of complexities to my life.
Not to mention, again, having to deal with all the minor details of Win32
security.

To remind you, I'm trying to find out if my code has write access to a
file,
on a framework that support multiply users, networks and such, this should
be a snap.
Instead...

Opening a file and catching the exception is the only easy way that I've,
and that is *not acceptable*.
</rant>

Seriously now, I really need a way to solve this problem, preferably with
something like:
FileAccess.Verify(filename,WriteAccess);

Thanks in advance,
Ayende Rahien


Nov 16 '05 #3
"Ayende Rahien" <Ay****@no.spam> wrote in
news:O3**************@TK2MSFTNGP12.phx.gbl:
<rant warning="I'm pissed off and have to vent" request="need help>
For the last couple of hours I'm struggling with a very *annoying*
problem. How to check if a user has a write access to a file?
Considerring that .Net is supposed to be a system for writing
applications for servers & clients, which in both cases has may have
multi-users, I'm amazed that this is not possible in the framework.
Initially I looked for something like:

System.IO.File.Access(string Filename, PermissionAccess);

Nothing!

I happened to run across some code in this very same newsgroup asking
basically the same question - I'll repost it for you assuming that you
didn't see it. This isn't my code and I haven't tested it, so use at your
own risk... I've included a few of the headers as well.

------------------

Subject: Re: Get ACL
From: "Willy Denoyette [MVP]" <wi*************@pandora.be>
Newsgroups: microsoft.public.dotnet.languages.csharp

You shouldn't use "unsupported" stuff like Win32Security.dll, use the
System.DirectoryServices (XP and higher) or System.Management namespace
instead.
Next is a complete example illustrating how to dump the ACE's from a File
object DACL using System.Management classes.

using System;
using System.Management;
using System.Collections;
// Access mask (see AccessMask property)
[Flags]
enum Mask : uint
{
FileReadData = 0x00000001,
FileWriteData = 0x00000002,
FileAppendData = 0x00000004,
FileReadEA = 0x00000008,
FileWriteEA = 0x00000010,
FileExecute = 0x00000020,
FileDeleteChild = 0x00000040,
FileReadAttributes = 0x00000080,
FileWriteAttributes= 0x00000100,

Delete = 0x00010000,
ReadControl = 0x00020000,
WriteDac = 0x00040000,
WriteOwner = 0x00080000,
Synchronize = 0x00100000,

AccessSystemSecurity = 0x01000000,
MaximumAllowed = 0x02000000,

GenericAll = 0x10000000,
GenericExecute= 0x20000000,
GenericWrite = 0x40000000,
GenericRead = 0x80000000
}
[Flags]
enum AceFlags : int
{
ObjectInheritAce = 1,
ContainerInheritAce = 2,
NoPropagateInheritAce = 4,
InheritOnlyAce = 8,
InheritedAce = 16
}

[Flags]
enum AceType : int
{
AccessAllowed = 0,
AccessDenied = 1,
Audit = 2
}
class Tester {
public static void Main() {
string fileObject = @"c:\\pipo\\t.txt"; // Watch the double Backslashes
using(ManagementObject lfs = new
ManagementObject(@"Win32_LogicalFileSecuritySettin g.Path=" + "'" +
fileObject + "'"))
{
// Get the security descriptor for this object
// Dump all trustees (this includes owner)
ManagementBaseObject outParams =
lfs.InvokeMethod("GetSecurityDescriptor", null, null);
if (((uint)(outParams.Properties["ReturnValue"].Value)) == 0) // if
success
{
ManagementBaseObject secDescriptor =
((ManagementBaseObject)(outParams.Properties["Descriptor"].Value));
//The DACL is an array of Win32_ACE objects.
ManagementBaseObject[] dacl =
((ManagementBaseObject[])(secDescriptor.Properties["Dacl"].Value));
DumpACEs(dacl);

}
}
}

static void DumpACEs(ManagementBaseObject[] dacl)
{
foreach(ManagementBaseObject mbo in dacl){
Console.WriteLine("\n---------\nMask: {0:X} - Flags: {1} - Type: {2}",
mbo["AccessMask"], mbo["AceFlags"], mbo["AceType"]);
// Access allowed/denied ACE
if(Convert.ToInt32(mbo["AceType"]) == (int)AceType.AccessDenied)
Console.WriteLine("DENIED ACE TYPE");
else
Console.WriteLine("ALLOWED ACE TYPE");
// Dump trustees
ManagementBaseObject Trustee = ((ManagementBaseObject)(mbo["Trustee"]));
Console.WriteLine("Name: {0} - Domain: {1} - SID {2}\n",
Trustee.Properties["Name"].Value,
Trustee.Properties["Domain"].Value,
Trustee.Properties["SIDString"].Value);
// Dump ACE mask in readable form
UInt32 mask = (UInt32)mbo["AccessMask"];
Console.WriteLine(Enum.Format(typeof(Mask), mask, "g"));
}
}
}

Nov 16 '05 #4
Michael Bray wrote:
"Ayende Rahien" <Ay****@no.spam> wrote in
news:O3**************@TK2MSFTNGP12.phx.gbl:

<rant warning="I'm pissed off and have to vent" request="need help>
For the last couple of hours I'm struggling with a very *annoying*
problem. How to check if a user has a write access to a file?
Considerring that .Net is supposed to be a system for writing
applications for servers & clients, which in both cases has may have
multi-users, I'm amazed that this is not possible in the framework.
Initially I looked for something like:

System.IO.File.Access(string Filename, PermissionAccess);

Nothing!
I happened to run across some code in this very same newsgroup asking
basically the same question - I'll repost it for you assuming that you
didn't see it. This isn't my code and I haven't tested it, so use at your
own risk... I've included a few of the headers as well.


Thanks a lot.
Could you show me how to use this to check if I've write access to the file?

------------------

Subject: Re: Get ACL
From: "Willy Denoyette [MVP]" <wi*************@pandora.be>
Newsgroups: microsoft.public.dotnet.languages.csharp

You shouldn't use "unsupported" stuff like Win32Security.dll, use the
System.DirectoryServices (XP and higher) or System.Management namespace
instead.
Next is a complete example illustrating how to dump the ACE's from a File
object DACL using System.Management classes.

using System;
using System.Management;
using System.Collections;
// Access mask (see AccessMask property)
[Flags]
enum Mask : uint
{
FileReadData = 0x00000001,
FileWriteData = 0x00000002,
FileAppendData = 0x00000004,
FileReadEA = 0x00000008,
FileWriteEA = 0x00000010,
FileExecute = 0x00000020,
FileDeleteChild = 0x00000040,
FileReadAttributes = 0x00000080,
FileWriteAttributes= 0x00000100,

Delete = 0x00010000,
ReadControl = 0x00020000,
WriteDac = 0x00040000,
WriteOwner = 0x00080000,
Synchronize = 0x00100000,

AccessSystemSecurity = 0x01000000,
MaximumAllowed = 0x02000000,

GenericAll = 0x10000000,
GenericExecute= 0x20000000,
GenericWrite = 0x40000000,
GenericRead = 0x80000000
}
[Flags]
enum AceFlags : int
{
ObjectInheritAce = 1,
ContainerInheritAce = 2,
NoPropagateInheritAce = 4,
InheritOnlyAce = 8,
InheritedAce = 16
}

[Flags]
enum AceType : int
{
AccessAllowed = 0,
AccessDenied = 1,
Audit = 2
}
class Tester {
public static void Main() {
string fileObject = @"c:\\pipo\\t.txt"; // Watch the double Backslashes
using(ManagementObject lfs = new
ManagementObject(@"Win32_LogicalFileSecuritySettin g.Path=" + "'" +
fileObject + "'"))
{
// Get the security descriptor for this object
// Dump all trustees (this includes owner)
ManagementBaseObject outParams =
lfs.InvokeMethod("GetSecurityDescriptor", null, null);
if (((uint)(outParams.Properties["ReturnValue"].Value)) == 0) // if
success
{
ManagementBaseObject secDescriptor =
((ManagementBaseObject)(outParams.Properties["Descriptor"].Value));
//The DACL is an array of Win32_ACE objects.
ManagementBaseObject[] dacl =
((ManagementBaseObject[])(secDescriptor.Properties["Dacl"].Value));
DumpACEs(dacl);

}
}
}

static void DumpACEs(ManagementBaseObject[] dacl)
{
foreach(ManagementBaseObject mbo in dacl){
Console.WriteLine("\n---------\nMask: {0:X} - Flags: {1} - Type: {2}",
mbo["AccessMask"], mbo["AceFlags"], mbo["AceType"]);
// Access allowed/denied ACE
if(Convert.ToInt32(mbo["AceType"]) == (int)AceType.AccessDenied)
Console.WriteLine("DENIED ACE TYPE");
else
Console.WriteLine("ALLOWED ACE TYPE");
// Dump trustees
ManagementBaseObject Trustee = ((ManagementBaseObject)(mbo["Trustee"]));
Console.WriteLine("Name: {0} - Domain: {1} - SID {2}\n",
Trustee.Properties["Name"].Value,
Trustee.Properties["Domain"].Value,
Trustee.Properties["SIDString"].Value);
// Dump ACE mask in readable form
UInt32 mask = (UInt32)mbo["AccessMask"];
Console.WriteLine(Enum.Format(typeof(Mask), mask, "g"));
}
}
}

Nov 16 '05 #5
Wow I posted late I guess, if your doing a library then you want to use the
WMI method. I believe one of the other posters posted a previous example of
doing this from a former thread.

-Enjoy!!

-Evan
"Evan Freeman[C++ Samuri]" <Ev**********@fmr.com> wrote in message
news:3n**************@news-srv1.fmr.com...
Heyas

FileIOPermission is a Code Access Security permission, not a Windows
role-based security permission. What you want is the ability to examine the security descriptor on the file and examine the rights of the various
Windows trustees in the entries in the DACL.

There are a couple of ways to do this. You could use COM interop and the
IADsSecurityUtility interface in ADSI, or you could use WMI, or use
the Win32 security .NET wrapper on GotDotNet that talks directly to the
Windows APIs.

Hint: The wrapper is the one you want.

-Enjoy!!

-Evan
"Ayende Rahien" <Ay****@no.spam> wrote in message
news:O3**************@TK2MSFTNGP12.phx.gbl...
<rant warning="I'm pissed off and have to vent" request="need help>
For the last couple of hours I'm struggling with a very *annoying* problem.
How to check if a user has a write access to a file?
Considerring that .Net is supposed to be a system for writing applications for servers & clients, which in both cases has may have multi-users, I'm amazed that this is not possible in the framework.
Initially I looked for something like:

System.IO.File.Access(string Filename, PermissionAccess);

Nothing!

Then I thought about System.Security.Permissions, and there is was, clear as
day FileIOPermission a class which "Controls the ability to access
files and folders."
But no! FileIOPermission works for .Net permissions, it doesn't do Win32
permissions!

Considerring that the framework is supposed to run on server class
platforms, why the omission?

In C & C++ I can do _access() and get the info I want, in .Net? I get to
delve into:

A> Interop code.
B> Win32 Security.

I can handle Interop if I absolutely have to, but even on a good day,

using
C++ I don't like Win32 Security, and all the tricks that are used there.
I checked ACLs in .Net

http://www.gotdotnet.com/community/u...mpleguid=e6098 575-dda0-48b8-9abf-e0705af065d9
No go, it requires me to add a component that is bigger then my code just
to
do so, and add several level of complexities to my life.
Not to mention, again, having to deal with all the minor details of

Win32 security.

To remind you, I'm trying to find out if my code has write access to a

file,
on a framework that support multiply users, networks and such, this should be a snap.
Instead...

Opening a file and catching the exception is the only easy way that I've, and that is *not acceptable*.
</rant>

Seriously now, I really need a way to solve this problem, preferably with something like:
FileAccess.Verify(filename,WriteAccess);

Thanks in advance,
Ayende Rahien


Nov 16 '05 #6
Ayende Rahien <Ay****@nospam.com> wrote in
news:eN**************@tk2msftngp13.phx.gbl:

Thanks a lot.
Could you show me how to use this to check if I've write access to the
file?


As I said, its not my code and I haven't tested it. It just seemed
relevant to what you were looking for. I don't have any direct knowledge
of how it works, so I can't help you here. The post is a current post in
this newsgroup - perhaps you could reset your newsreader and search for
this and ask the original author.

-mdb
Nov 16 '05 #7
I feel your pain brotherrman. I feel your pain...

On Thu, 8 Apr 2004 15:54:15 +0200, "Ayende Rahien" <Ay****@no.spam>
wrote:
<rant warning="I'm pissed off and have to vent" request="need help>
For the last couple of hours I'm struggling with a very *annoying* problem.
How to check if a user has a write access to a file?
Considerring that .Net is supposed to be a system for writing applications
for servers & clients, which in both cases has may have multi-users, I'm
amazed that this is not possible in the framework.
Initially I looked for something like:

System.IO.File.Access(string Filename, PermissionAccess);

Nothing!

Then I thought about System.Security.Permissions, and there is was, clear as
day FileIOPermission a class which "Controls the ability to access files
and folders."
But no! FileIOPermission works for .Net permissions, it doesn't do Win32
permissions!

Considerring that the framework is supposed to run on server class
platforms, why the omission?

In C & C++ I can do _access() and get the info I want, in .Net? I get to
delve into:

A> Interop code.
B> Win32 Security.

I can handle Interop if I absolutely have to, but even on a good day, using
C++ I don't like Win32 Security, and all the tricks that are used there.
I checked ACLs in .Net
http://www.gotdotnet.com/community/u...f-e0705af065d9
No go, it requires me to add a component that is bigger then my code just to
do so, and add several level of complexities to my life.
Not to mention, again, having to deal with all the minor details of Win32
security.

To remind you, I'm trying to find out if my code has write access to a file,
on a framework that support multiply users, networks and such, this should
be a snap.
Instead...

Opening a file and catching the exception is the only easy way that I've,
and that is *not acceptable*.
</rant>

Seriously now, I really need a way to solve this problem, preferably with
something like:
FileAccess.Verify(filename,WriteAccess);

Thanks in advance,
Ayende Rahien


Nov 16 '05 #8
You hit the nail on the head when you talked about multi-user environments. In a multi-user environment the only time it is safe to assume that a user has write access to a file is at the point when the user successfully opens the file for writing. With your proposed File.Access type functions you can get race conditions between multiple threads, e.g,

User A - have I got write access - yes, so I can open the fil
User B - opens the same file for writing, which denies anyone else write acces
User A - now tries to open the file - but they no longer have write access, so this fails

That's why File.Open throws an UnauthorizedAccessException, so you can take appropriate action (e.g., pause for a bit, loop round, and then try again). The C _access function is not suitable for multi-user environments.
Nov 16 '05 #9
I suppose you can't just write to the file and see if it works? A write
access check won't tell you about disk quota problems, for instance.

--
John Saunders
John.Saunders at SurfControl.com

"Ayende Rahien" <Ay****@no.spam> wrote in message
news:O3****************@TK2MSFTNGP12.phx.gbl...
<rant warning="I'm pissed off and have to vent" request="need help>
For the last couple of hours I'm struggling with a very *annoying* problem. How to check if a user has a write access to a file?
Considerring that .Net is supposed to be a system for writing applications
for servers & clients, which in both cases has may have multi-users, I'm
amazed that this is not possible in the framework.
Initially I looked for something like:

System.IO.File.Access(string Filename, PermissionAccess);

Nothing!

Then I thought about System.Security.Permissions, and there is was, clear as day FileIOPermission a class which "Controls the ability to access files
and folders."
But no! FileIOPermission works for .Net permissions, it doesn't do Win32
permissions!

Considerring that the framework is supposed to run on server class
platforms, why the omission?

In C & C++ I can do _access() and get the info I want, in .Net? I get to
delve into:

A> Interop code.
B> Win32 Security.

I can handle Interop if I absolutely have to, but even on a good day, using C++ I don't like Win32 Security, and all the tricks that are used there.
I checked ACLs in .Net
http://www.gotdotnet.com/community/u...f-e0705af065d9 No go, it requires me to add a component that is bigger then my code just to do so, and add several level of complexities to my life.
Not to mention, again, having to deal with all the minor details of Win32
security.

To remind you, I'm trying to find out if my code has write access to a file, on a framework that support multiply users, networks and such, this should
be a snap.
Instead...

Opening a file and catching the exception is the only easy way that I've,
and that is *not acceptable*.
</rant>

Seriously now, I really need a way to solve this problem, preferably with
something like:
FileAccess.Verify(filename,WriteAccess);

Thanks in advance,
Ayende Rahien

Nov 16 '05 #10
This is nice, but won't do me any good, as teh FileInfo doesn't contain
permission checking, only attributes (Yes, I'll have access to the
read-only, but that won't help if I don't have write access to the file.)

gary hitch wrote:
see attatched vs .net project file

the main thing happens here:

private void frmFileAttributes_Load(object sender, System.EventArgs e)
{
string[] lvData = new string[5]; // store file data
string[] stringFiles = Directory.GetFiles( @"C:\" );
string stringFileName = "";
string attribute = "";
Int64 lFileSize = 0;

//loop through files in C:\
foreach ( string stringFile in stringFiles )
{
stringFileName = stringFile;
FileInfo objFileInfo = new FileInfo( stringFileName );
lFileSize = objFileInfo.Length;

// file attributes are here :
attribute = objFileInfo.Attributes.ToString(); // right here !

//..... store the data
lvData[0] = GetPathName(stringFileName);
lvData[1] = lFileSize.ToString();
lvData[2] = attribute;

//Create actual list item
ListViewItem lvItem = new ListViewItem( lvData, 0 );
lv.Items.Add( lvItem );
}
}

my pleasure - hope you find it useful
8-)

Nov 16 '05 #11
John Saunders wrote:
I suppose you can't just write to the file and see if it works? A write
access check won't tell you about disk quota problems, for instance.


It's a very small utility, and I'm going to do a very intensive use of it.
Exceptions are *slow*, really(!!) slow.
Nov 16 '05 #12
What's wrong with simply attempting to open the file in Write mode and if it doesn't work (i.e. exception thrown) then you know that you don't have write access to it? Something like:

public class Form1 : System.Windows.Forms.Form
{
private System.ComponentModel.IContainer components;
private FileStream myFile = null;

public Form1()
{
try
{
myFile = File.OpenWrite( @"C:\test.txt" );
}
catch( Exception e )
{
MessageBox.Show( "Cannot open file. Error: " + e.Message );
}
...
}
This is nice, but won't do me any good, as teh FileInfo doesn't contain
permission checking, only attributes (Yes, I'll have access to the
read-only, but that won't help if I don't have write access to the file.)

gary hitch wrote:
see attatched vs .net project file

the main thing happens here:

private void frmFileAttributes_Load(object sender, System.EventArgs e)
{
string[] lvData = new string[5]; // store file data
string[] stringFiles = Directory.GetFiles( @"C:\" );
string stringFileName = "";
string attribute = "";
Int64 lFileSize = 0;

//loop through files in C:\
foreach ( string stringFile in stringFiles )
{
stringFileName = stringFile;
FileInfo objFileInfo = new FileInfo( stringFileName );
lFileSize = objFileInfo.Length;

// file attributes are here :
attribute = objFileInfo.Attributes.ToString(); // right here !

//..... store the data
lvData[0] = GetPathName(stringFileName);
lvData[1] = lFileSize.ToString();
lvData[2] = attribute;

//Create actual list item
ListViewItem lvItem = new ListViewItem( lvData, 0 );
lv.Items.Add( lvItem );
}
}

my pleasure - hope you find it useful
8-)


[microsoft.public.dotnet.languages.csharp]

Nov 16 '05 #13
Then disregard my post regarding File.OpenWrite?.
-Mark Schmidt?

It's a very small utility, and I'm going to do a very intensive use of it.
Exceptions are *slow*, really(!!) slow.


Nov 16 '05 #14
astanley wrote:
You hit the nail on the head when you talked about multi-user environments. In a multi-user environment the only time it is safe to assume that a user has write access to a file is at the point when the user successfully opens the file for writing. With your proposed File.Access type functions you can get race conditions between multiple threads, e.g,.

User A - have I got write access - yes, so I can open the file
User B - opens the same file for writing, which denies anyone else write access
User A - now tries to open the file - but they no longer have write access, so this fails.
For this I can use mutexes, if I've to.
I don't see this as a possible problem, because I already uses
multi-threading and syncronize between them.

That's why File.Open throws an UnauthorizedAccessException, so you can take appropriate action (e.g., pause for a bit, loop round, and then try again). The C _access function is not suitable for multi-user environments.


Yes, except that I've a tight loop there, and exceptions are very slow.
Beside, I need to give the user input, and that isn't possible with
exceptions.
Beside, I *really* dislike the try-catch as a replacement for a function
call that should exist.
Nov 16 '05 #15
Yes, exceptions are expensive - if thrown. The question is, do you
anticipate most of the requests to be denied? If only a small percentage of
them are going to be attempts to use a file the user has no access to - then
you should be fine, as you will only pay the penalty of throwing/catching
exceptions in this case, which isn't going to amount to that much.

"Ayende Rahien" <Ay****@nospam.com> wrote in message
news:OX**************@TK2MSFTNGP09.phx.gbl...
John Saunders wrote:
I suppose you can't just write to the file and see if it works? A write
access check won't tell you about disk quota problems, for instance.


It's a very small utility, and I'm going to do a very intensive use of it.
Exceptions are *slow*, really(!!) slow.

Nov 16 '05 #16
Ayende Rahien <Ay****@nospam.com> wrote:
I suppose you can't just write to the file and see if it works? A write
access check won't tell you about disk quota problems, for instance.


It's a very small utility, and I'm going to do a very intensive use of it.
Exceptions are *slow*, really(!!) slow.


The first exception thrown (of some types) *can* be slow, depending on
what resources need to be loaded. After that, they're pretty fast. I
seem to remember my box is able to throw about a hundred thousand
exceptions a second. Are you really expecting to fail to write to
*that* many files?

If you're worried about the first exception being slow, you could
always start a new thread at the start of program execution so that it
gets that over and done with in the background - then you won't face
the performance hit later on if you get an exception for some other
reason.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #17
Ok, I think I misunderstood your purpose.
Did you check - FileIOPermission.GetPathList Method and the param
FileIOPermissionAccess Enumeration ?

BTW, the exception catch thing seems to me to be the easiest way to go with
your requirements

8-)

"Ayende Rahien" <Ay****@no.spam> wrote in message
news:O3**************@TK2MSFTNGP12.phx.gbl...
<rant warning="I'm pissed off and have to vent" request="need help>
For the last couple of hours I'm struggling with a very *annoying* problem. How to check if a user has a write access to a file?
Considerring that .Net is supposed to be a system for writing applications
for servers & clients, which in both cases has may have multi-users, I'm
amazed that this is not possible in the framework.
Initially I looked for something like:

System.IO.File.Access(string Filename, PermissionAccess);

Nothing!

Then I thought about System.Security.Permissions, and there is was, clear as day FileIOPermission a class which "Controls the ability to access files
and folders."
But no! FileIOPermission works for .Net permissions, it doesn't do Win32
permissions!

Considerring that the framework is supposed to run on server class
platforms, why the omission?

In C & C++ I can do _access() and get the info I want, in .Net? I get to
delve into:

A> Interop code.
B> Win32 Security.

I can handle Interop if I absolutely have to, but even on a good day, using C++ I don't like Win32 Security, and all the tricks that are used there.
I checked ACLs in .Net
http://www.gotdotnet.com/community/u...mpleguid=e6098
575-dda0-48b8-9abf-e0705af065d9 No go, it requires me to add a component that is bigger then my code just to do so, and add several level of complexities to my life.
Not to mention, again, having to deal with all the minor details of Win32
security.

To remind you, I'm trying to find out if my code has write access to a file, on a framework that support multiply users, networks and such, this should
be a snap.
Instead...

Opening a file and catching the exception is the only easy way that I've,
and that is *not acceptable*.
</rant>

Seriously now, I really need a way to solve this problem, preferably with
something like:
FileAccess.Verify(filename,WriteAccess);

Thanks in advance,
Ayende Rahien

Nov 16 '05 #18
Stay away from ACL based File access checks in user applications, they are
an order of magnitude slower than exception.

Willy.

"Ayende Rahien" <Ay****@nospam.com> wrote in message
news:OX**************@TK2MSFTNGP09.phx.gbl...
John Saunders wrote:
I suppose you can't just write to the file and see if it works? A write
access check won't tell you about disk quota problems, for instance.


It's a very small utility, and I'm going to do a very intensive use of it.
Exceptions are *slow*, really(!!) slow.

Nov 16 '05 #19
Willy Denoyette [MVP] wrote:
Stay away from ACL based File access checks in user applications, they are
an order of magnitude slower than exception.


Why?
Nov 16 '05 #20
Jon Skeet [C# MVP] wrote:
Ayende Rahien <Ay****@nospam.com> wrote:
I suppose you can't just write to the file and see if it works? A write
access check won't tell you about disk quota problems, for instance.


It's a very small utility, and I'm going to do a very intensive use of it.
Exceptions are *slow*, really(!!) slow.

The first exception thrown (of some types) *can* be slow, depending on
what resources need to be loaded. After that, they're pretty fast. I
seem to remember my box is able to throw about a hundred thousand
exceptions a second. Are you really expecting to fail to write to
*that* many files?

If you're worried about the first exception being slow, you could
always start a new thread at the start of program execution so that it
gets that over and done with in the background - then you won't face
the performance hit later on if you get an exception for some other
reason.


Oh, well, I think that I don't have a choice in the matter.
I will simply cache the exception's result and live with the inefficency.
Nov 16 '05 #21
I'm the "author" of this example, but be warned, you should never ever use
this to check NTFS file permissions in user applications (other than FS
management applications), in order to determine whether you have read, write
or whatever access to a file.
Just open the file in the mode you need and let the filesystem do it's job,
all you need to do is handle the exception thrown.

Willy.

"Michael Bray" <mb*******************@SkPiAlMl.ctiusa.com> wrote in message
news:Xn**********************************@207.46.2 48.16...
"Ayende Rahien" <Ay****@no.spam> wrote in
news:O3**************@TK2MSFTNGP12.phx.gbl:
<rant warning="I'm pissed off and have to vent" request="need help>
For the last couple of hours I'm struggling with a very *annoying*
problem. How to check if a user has a write access to a file?
Considerring that .Net is supposed to be a system for writing
applications for servers & clients, which in both cases has may have
multi-users, I'm amazed that this is not possible in the framework.
Initially I looked for something like:

System.IO.File.Access(string Filename, PermissionAccess);

Nothing!

I happened to run across some code in this very same newsgroup asking
basically the same question - I'll repost it for you assuming that you
didn't see it. This isn't my code and I haven't tested it, so use at your
own risk... I've included a few of the headers as well.

------------------

Subject: Re: Get ACL
From: "Willy Denoyette [MVP]" <wi*************@pandora.be>
Newsgroups: microsoft.public.dotnet.languages.csharp

You shouldn't use "unsupported" stuff like Win32Security.dll, use the
System.DirectoryServices (XP and higher) or System.Management namespace
instead.
Next is a complete example illustrating how to dump the ACE's from a File
object DACL using System.Management classes.

using System;
using System.Management;
using System.Collections;
// Access mask (see AccessMask property)
[Flags]
enum Mask : uint
{
FileReadData = 0x00000001,
FileWriteData = 0x00000002,
FileAppendData = 0x00000004,
FileReadEA = 0x00000008,
FileWriteEA = 0x00000010,
FileExecute = 0x00000020,
FileDeleteChild = 0x00000040,
FileReadAttributes = 0x00000080,
FileWriteAttributes= 0x00000100,

Delete = 0x00010000,
ReadControl = 0x00020000,
WriteDac = 0x00040000,
WriteOwner = 0x00080000,
Synchronize = 0x00100000,

AccessSystemSecurity = 0x01000000,
MaximumAllowed = 0x02000000,

GenericAll = 0x10000000,
GenericExecute= 0x20000000,
GenericWrite = 0x40000000,
GenericRead = 0x80000000
}
[Flags]
enum AceFlags : int
{
ObjectInheritAce = 1,
ContainerInheritAce = 2,
NoPropagateInheritAce = 4,
InheritOnlyAce = 8,
InheritedAce = 16
}

[Flags]
enum AceType : int
{
AccessAllowed = 0,
AccessDenied = 1,
Audit = 2
}
class Tester {
public static void Main() {
string fileObject = @"c:\\pipo\\t.txt"; // Watch the double Backslashes
using(ManagementObject lfs = new
ManagementObject(@"Win32_LogicalFileSecuritySettin g.Path=" + "'" +
fileObject + "'"))
{
// Get the security descriptor for this object
// Dump all trustees (this includes owner)
ManagementBaseObject outParams =
lfs.InvokeMethod("GetSecurityDescriptor", null, null);
if (((uint)(outParams.Properties["ReturnValue"].Value)) == 0) // if
success
{
ManagementBaseObject secDescriptor =
((ManagementBaseObject)(outParams.Properties["Descriptor"].Value));
//The DACL is an array of Win32_ACE objects.
ManagementBaseObject[] dacl =
((ManagementBaseObject[])(secDescriptor.Properties["Dacl"].Value));
DumpACEs(dacl);

}
}
}

static void DumpACEs(ManagementBaseObject[] dacl)
{
foreach(ManagementBaseObject mbo in dacl){
Console.WriteLine("\n---------\nMask: {0:X} - Flags: {1} - Type: {2}",
mbo["AccessMask"], mbo["AceFlags"], mbo["AceType"]);
// Access allowed/denied ACE
if(Convert.ToInt32(mbo["AceType"]) == (int)AceType.AccessDenied)
Console.WriteLine("DENIED ACE TYPE");
else
Console.WriteLine("ALLOWED ACE TYPE");
// Dump trustees
ManagementBaseObject Trustee = ((ManagementBaseObject)(mbo["Trustee"]));
Console.WriteLine("Name: {0} - Domain: {1} - SID {2}\n",
Trustee.Properties["Name"].Value,
Trustee.Properties["Domain"].Value,
Trustee.Properties["SIDString"].Value);
// Dump ACE mask in readable form
UInt32 mask = (UInt32)mbo["AccessMask"];
Console.WriteLine(Enum.Format(typeof(Mask), mask, "g"));
}
}
}

Nov 16 '05 #22
Heyas

FileIOPermission is a Code Access Security permission, not a Windows
role-based security permission. What you want is the ability to examine the
security descriptor on the file and examine the rights of the various
Windows trustees in the entries in the DACL.

There are a couple of ways to do this. You could use COM interop and the
IADsSecurityUtility interface in ADSI, or you could use WMI, or use
the Win32 security .NET wrapper on GotDotNet that talks directly to the
Windows APIs.

Hint: The wrapper is the one you want.

-Enjoy!!

-Evan
"Ayende Rahien" <Ay****@no.spam> wrote in message
news:O3**************@TK2MSFTNGP12.phx.gbl...
<rant warning="I'm pissed off and have to vent" request="need help>
For the last couple of hours I'm struggling with a very *annoying* problem. How to check if a user has a write access to a file?
Considerring that .Net is supposed to be a system for writing applications
for servers & clients, which in both cases has may have multi-users, I'm
amazed that this is not possible in the framework.
Initially I looked for something like:

System.IO.File.Access(string Filename, PermissionAccess);

Nothing!

Then I thought about System.Security.Permissions, and there is was, clear as day FileIOPermission a class which "Controls the ability to access files
and folders."
But no! FileIOPermission works for .Net permissions, it doesn't do Win32
permissions!

Considerring that the framework is supposed to run on server class
platforms, why the omission?

In C & C++ I can do _access() and get the info I want, in .Net? I get to
delve into:

A> Interop code.
B> Win32 Security.

I can handle Interop if I absolutely have to, but even on a good day, using C++ I don't like Win32 Security, and all the tricks that are used there.
I checked ACLs in .Net
http://www.gotdotnet.com/community/u...mpleguid=e6098
575-dda0-48b8-9abf-e0705af065d9 No go, it requires me to add a component that is bigger then my code just to do so, and add several level of complexities to my life.
Not to mention, again, having to deal with all the minor details of Win32
security.

To remind you, I'm trying to find out if my code has write access to a file, on a framework that support multiply users, networks and such, this should
be a snap.
Instead...

Opening a file and catching the exception is the only easy way that I've,
and that is *not acceptable*.
</rant>

Seriously now, I really need a way to solve this problem, preferably with
something like:
FileAccess.Verify(filename,WriteAccess);

Thanks in advance,
Ayende Rahien

Nov 16 '05 #23
First, to check the ACL's the NTFS Filesystem subsystem has to read them
from the filesystem object (File or Directory), and return a
Securitydescriptor (SD) to the caller.
Then you (the caller) have to scan each ACE in the DACL contained in the SD,
for the callers SID, if an entry is found with his SID, you can check the
required access privilege from this entry (but you are not done yet).
If the direct SID is not found in one of the ACE's, you have to check
whether the caller's SID is a member of the group SID's, if so, check the
required access privilege from this (group) entry. This step is extremely
expensive has you have to check for group membership on the local SD
database (for local groups) or the DOMAIN Security database (for global
groups).

Now, you need to scan the SACL exactly the same way as the DACL, if the
required access is explicitly denied, you cannot use the result obtained in
previous steps, else you can use the result obtained from previous steps.
(Well actually you need to to the SACL scan first, but I hope you got the
point)
Willy.

"Ayende Rahien" <Ay****@nospam.com> wrote in message
news:ee**************@TK2MSFTNGP10.phx.gbl...
Willy Denoyette [MVP] wrote:
Stay away from ACL based File access checks in user applications, they
are an order of magnitude slower than exception.


Why?

Nov 16 '05 #24


"Evan Freeman[C++ Samuri]" <Ev**********@fmr.com> wrote in message
news:3n**************@news-srv1.fmr.com...
Heyas

FileIOPermission is a Code Access Security permission, not a Windows
role-based security permission. What you want is the ability to examine
the
security descriptor on the file and examine the rights of the various
Windows trustees in the entries in the DACL.

There are a couple of ways to do this. You could use COM interop and the
IADsSecurityUtility interface in ADSI, or you could use WMI, or use
the Win32 security .NET wrapper on GotDotNet that talks directly to the
Windows APIs.

Hint: The wrapper is the one you want.

-Enjoy!!

-Evan

While you can use both System.Management (WMI) and System.Directory (and
ADSI interop) to perform access checks on File objects, I would suggest you
never do this in user applications other than "FS management" (ACLEDIT)
style applications.

Note:the upcoming version of the framework will have this all included in
the System.Security.AccessCheck namespace, but using the new classes is just
as complex as using System.Management (WMI) and System.Directory (and ADSI),
just because ACL programming is really a complex matter.

Willy.
Nov 16 '05 #25
"Ayende Rahien" <Ay****@nospam.com> wrote in message
news:OX**************@TK2MSFTNGP09.phx.gbl...
John Saunders wrote:
I suppose you can't just write to the file and see if it works? A write
access check won't tell you about disk quota problems, for instance.


It's a very small utility, and I'm going to do a very intensive use of it.
Exceptions are *slow*, really(!!) slow.


I simply question the need for your utility. What would happen to your
application if you write your access check like this:

public bool CheckAccess(FileInfo fi)
{
return true;
}

What would probably happen is that most of your write accesses would
succeed, but that some would fail and throw an exception. This is the way
to go. Let the operating system tell you whether or not you can write to a
particular file. In fact, if you go checking ACLs, you could find that you
have write access to a file but that you cannot write to it at all. This
could be because your users disk quota is exhausted, because the disk is
full, because the disk is write-locked, or for any other reason you've never
heard of and can't imagine. The OS has a better imagination than you do. :-)

--
John Saunders
John.Saunders at SurfControl.com
Nov 16 '05 #26
It uses WMI to get the permissions. So go take a look at the WMI iformation
on MSDN.

-Enjoy!!

-Evan

"Michael Bray" <mb*******************@SkPiAlMl.ctiusa.com> wrote in message
news:Xn**********************************@207.46.2 48.16...
Ayende Rahien <Ay****@nospam.com> wrote in
news:eN**************@tk2msftngp13.phx.gbl:

Thanks a lot.
Could you show me how to use this to check if I've write access to the
file?


As I said, its not my code and I haven't tested it. It just seemed
relevant to what you were looking for. I don't have any direct knowledge
of how it works, so I can't help you here. The post is a current post in
this newsgroup - perhaps you could reset your newsreader and search for
this and ask the original author.

-mdb

Nov 16 '05 #27

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

23
by: Ayende Rahien | last post by:
<rant warning="I'm pissed off and have to vent" request="need help> For the last couple of hours I'm struggling with a very *annoying* problem. How to check if a user has a write access to a file?...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.