0

My thought is to use CreateFile from kernel32 and check for sharing violations. I believe this will work because I watched the file system activity with Process Monitor while issuing a rename command from CMD that I knew would fail and the last activity was a failed CreateFile call that resulted in a sharing violation.

This is the Process Monitor information on the call.

Desired Access: Read Attributes, Delete, Synchronize
Disposition: Open 
Options: Synchronous IO Non-Alert, Open Reparse Point 
Attributes: n/a 
ShareMode: Read, Write, Delete 
AllocationSize: n/a

Using this VB code, I produced a call which gave the same information in Process Monitor but did not cause the sharing violation.

CreateFile(theDirectoryPath, _
           FILE_READ_ATTRIBUTES Or DELETE Or SYNCHRONIZE, _
           FILE_SHARE_READ Or FILE_SHARE_WRITE Or FILE_SHARE_DELETE, _
           Nothing, _
           OPEN_EXISTING, _
           FILE_ATTRIBUTE_DIRECTORY Or FILE_FLAG_BACKUP_SEMANTICS _
               Or FILE_FLAG_OPEN_REPARSE_POINT, _
           Nothing)

The constants are pulled from various MSDN and pinvoke.net sources.

If I call the above code recursively on all subfolders it will eventually cause the sharing violation, but when CMD refused to rename, it did not recurse.

Yes, I know I could just try and catch the exception. But the point at which I want to know if the directory can be renamed and the point at which I want to rename the directory are not the same.

EDIT:

There may have been a source of confusion in this question. I am not concerned with permissions; I am concerned with file locks.

Instance Hunter
  • 7,837
  • 5
  • 44
  • 56

2 Answers2

3

Yes, I know I could just try and catch the exception. But the point at which I want to know if the directory can be renamed and the point at which I want to rename the directory are not the same.

In my opinion, this is a design problem that creates a race condition. If you check first and rename later, you will not know that the time of rename if your previous check was valid.

JP Alioto
  • 44,864
  • 6
  • 88
  • 112
  • You will if you know the single cause of all previous failures to rename and know that the user can prevent them if simply warned. – Instance Hunter Jun 29 '09 at 17:52
  • How can you ever prevent the OS from taking a file lock without locking it yourself? – JP Alioto Jun 29 '09 at 18:19
  • You can't. But you can be reasonably certain it won't happen if you know what has caused every instance of it happening in the past and know that a warning will prevent that from happening. – Instance Hunter Jun 29 '09 at 18:25
1

Untested, but this should work:

Dim fp As New FileIOPermission(FileIOPermissionAccess.Write, "C:\myfolderpath")
Try
    fp.Demand()
Catch e As SecurityException
    Console.WriteLine("I can't rename this folder.")
End Try

This will "demand" Read and Write permissions on the folder without actually renaming anything.

Edit: The above doesn't do what I thought it would, see Stephen's comment below.

If this doesn't work, perhaps attempting to rename the file with the same filename will trigger the security exception without actually doing anything destructive (though it will probably "touch" the directory).

richardtallent
  • 34,724
  • 14
  • 83
  • 123
  • As far as I can tell, this returns true (does not throw the exception) for all valid paths, including those that don't exist, the C: root and directories which cannot be renamed. – Instance Hunter Jun 29 '09 at 16:34
  • Corrected, I hope... I think the "Or" above must result in an OR search rather than an AND search, which was my intent. – richardtallent Jun 29 '09 at 17:02
  • Still returns true for all paths mentioned before. Just for kicks, I tried it with .AllAccess and it still had the same behavior. – Instance Hunter Jun 29 '09 at 17:56
  • 3
    This is a very common misunderstanding - FileIOPermissionAccess only tests Code Access Security (does the assembly have sufficient trust to access that file path) not File System Security(does the current user have permission to access that file or folder. – Stephen Martin Jun 29 '09 at 18:12
  • Renaming a file to itself is quite plainly documented as causing an IOException. I'm trying to be patient, but please do at least SOME research before suggesting anything else. – Instance Hunter Jun 29 '09 at 18:27
  • Daniel, no need to get testy. I wasn't trying to avoid the IOException in my other suggestion, I was trying to give you a way to test the rename permissions before renaming the file to *something else*. Your question refers to the need to know whether a file can be renamed *before* performing the action. Renaming it to itself is one way to do so. – richardtallent Jul 01 '09 at 16:32
  • Thanks for the clarification, Stephen... that makes a lot more sense. – richardtallent Jul 01 '09 at 16:33
  • Renaming it to itself doesn't tell you anything. It just throws an IOException. That's what I was saying. – Instance Hunter Jul 01 '09 at 20:56