How do I open a directory with CreateFile() - winapi

SetFileTime says that it must be given a handle opened with CreateFile referring to a file or directory. But what are the proper parameters to open a directory with CreateFile ?

Related

Should I close os.File before calling os.removeAll?

so if I've created a temp file in temp directory, used it and now I need to remove it(or them), should I call first file.Close() and then os.RemoveAll, or if I call os.RemoveAll it is unnecessary to close files? Is then file descriptor freed?
On linux removing a file causes its name to be removed from the file system but the block of storage will remain on disk while you still have an open file descriptor and removed only once that file descriptor (and any other file descriptors opened on that file) is closed. See https://linux.die.net/man/2/unlink
In go, the open file descriptor will not be closed just because you call os.RemoveAll() on a directory that contains the file.
I believe microsoft windows works differently: I think you will get an error when you try to remove a file that's currently being written to. That could be wrong, I'm no expert on Windows. But again, the open file descriptor will not be closed automatically.

What happens to permissions when a file goes to the recycle bin?

I have a problem related to file management done by a service application. My problem is that users are able to move files to the recycle bin for which I've created a hardlink, and once they do this, I loose the ability to list the hardlinks available.
This appears to only happen when the removed hardlink file sits inside the $RECYCLER folder but not on a folder with similar permissions on the same disk.
To replicate my problem assume one has a user account named Service with a suitable password.
On the current user account:
md C:\tmp
echo CONTENTS>C:\tmp\1
fsutil hardlink create C:\tmp\2 C:\tmp\1
That would have created a file named C:\tmp\1 and a hardlink to it named C:\tmp\2.
Now if you runas another terminal with user Service you can:
fsutil hardlink list C:\tmp\1
\tmp\1
\tmp\2
That works fine.
Now if you (as the original user) move the 2 file to the recycle bin, you cannot access the files as Service.
type C:\tmp\1
Access is denied.
fsutil hardlink list C:\tmp\1
Error: Access is denied.
That's because Explorer will have changed the DACL on the file to a restrictive one where only the current user, SYSTEM and an Administrator have access to the file.
If you do a icacls C:\tmp\1 /reset as the original user, now you can access the contents of the file as Service:
type C:\tmp\1
CONTENTS
But if you try to list the hardlinks, it will show you the first link and an access denied error:
fsutil hardlink list C:\tmp\1
\tmp\1
Error: Access is denied.
If you list the hardlinks on the file as the original user, you get to know the recycle bin path of the original file:
fsutil hardlink list C:\tmp\1
\tmp\1
\$Recycle.Bin\S-1-5-21-111111111-2222222222-3333333333-1002\$R1GX1HN
And if you move that file to another (as the original user) folder:
md C:\tmp2
move \$Recycle.Bin\S-1-5-21-111111111-2222222222-3333333333-1002\$R1GX1HN C:\tmp2
Now as Service you can list all the hardlinks:
fsutil hardlink list C:\tmp\1
\tmp\1
\tmp2\$R1GX1HN
Any idea why this may be happening?
Does this have anything to do with Mandatory Integrity Control?
As explained in the comments by #Eryk Sun, the problem is related to the way hardlinks are reported by Win32 API.
It appears that fsutil uses FindFirstFileName and FindNextFileName functions, both of which use NtQueryInformationFile which in turn returns a structure with entries of type FILE_LINK_ENTRY_INFORMATION which have the hardlink name and the parent folder NTFS ID.
The problem manifests itself when the caller does not have permission to open the containing folder to get its name (probably using OpenFileById and GetFinalPathByHandle).

unix shell: how to escapte a hidden directory name "."

I am using AIX version 6.1.0.0. I have a hiden directory name like ".sh". When I place the directory name into a variable, I always get a cannot find file error.
file_dir=/opt/.sh/scripts
$file_dir/Find_files.sh $file_dir/file_name
Errors: cat: 0652-050 Cannot open "file_name". A file or directory in the path name does not exist.
I believe the issue is that hidden directory name ".sh". How can I go around this issue?
Without knowing the permissions on the file, directory, subdirs and which user your using its hard to be a 100% sure. But related information about this error states the following:
Possible Causes
1. This error message may be displayed during a backup operation.
2. The system looked for a file that either does not exist or was specified incorrectly.
3. The system looked for a file for which you do not have write permission.
Personally I think its a permission issue with your directory or subdir, so make sure you have the correct access or ownership.

NTFS stream H:stream

Why I try to open NTFS stream named "file:stream" using CreateFile() - that's OK.
But when file is "H" and I got flash card reader on drive H:, CreateFile() tries to open file named "stream" on flash card, because argument passed to CreateFile() is "H:stream"!
How these named streams should be opened correctly?
In this oddball case, you can simply prepend .\ in front of file name or use full file path. For example, this works for me as expected:
.\H:stream

cocoa -- determine directory from which a tool was launched?

I have a command-line tool written in Cocoa. Let's call it processFile. So if I am in the terminal and I type in the command ./processFile foo, it looks for a file named foo.html in the same directory as the executable of processFile. If it finds one, it reads it and does some stuff to create fooProcessed.html.
Now I want to modify my tool so that it looks for foo.html in the directory from which it was launched. So if I am in the terminal with current directory ~/documents/html, and processFile executable is in usr/bin, and I type in
processFile foo
it will find and process the file ~/documents/foo.html.
The problem is that I don't know how to get the directory from which the tool was invoked. How can I do that?
That's the current working directory. First of all, any attempt to access the file just using its name and no path will automatically use the working directory. So, if you simply take "foo", append ".html", and attempt to open the file, that will work. If the user specified a relative path, like "subdir/foo", that would also work. It would resolve the relative path starting from the current working directory.
You can also query the working directory using the getcwd() routine.

Resources