SMB2 opens for Query Directory requests - winapi

Is there a way to definitely identify whether an open request sent by SMB2 client is for reading a file or enumerating the directory(SMB2 query directory request)? Sometimes, the requests are compounded and in some cases they are not. Does any flag in the open request indicate that the open which the client is attempting to do is to read the contents of the directory and not the file?
I know that the create option flag cannot be relied upon for this as few clients may ignore to set that flag.

Related

Distinction between open file modes with fanotify

I find it very very unclear what fanotify flags stand for.
Im using it for access control and would like to identify files opened for read and for write.
Taken from man:
FAN_OPEN_PERM An application wants to open a file or directory. The reader must write a response that determines whether the permission to open the filesystem object shall be granted.
Is it possible to allow only to read files, without write?
EDIT: I'm well aware of the fact that these can be realized when receiving FAN_CLOSE_WRITE and FAN_CLOSE_NOWRITE, but I want to make my access decision based on whether a file was opened for reading or for editing

In Windows is it always necessary to use a handle to access a file?

In other words, is it possible to access a file without a handle being utilized?
You could use the CreateFile()-API to create a handle to the raw file-system and then parse the file structure by yourself (this is more work as it sounds!)
Though this would require admin-rights. This wouldn't trigger any hooks you have on CreateFile() or other file-related API-functions.
This wouldn't create a handle to the file but you still need a handle to the device.
For code running in user mode, any operation on a file will involve a handle of some kind, though not necessarily to the file in question. There are APIs that don't expose the handle to the programmer, but there is always one there.
In kernel mode, although it is usual to use handles for file operations, it is not necessary. For example, the file server component doesn't appear to open file handles when it is accessing a file on behalf of a remote user.

How to only read a few lines from a remote file?

Before downloading file, I need to set up a way it (the .csv typically, but not always) will be parsed.
I don't want to download the whole file especially if the "headers" do not match what is expected.
Is there a way to only download up until a certain number of byes and then gracefully kill the connection?
There's no explicit support for this in an FTP protocol.
There's an expired draft for RANG command that would allow this:
https://datatracker.ietf.org/doc/html/draft-bryan-ftp-range-08
But that's obviously supported by only new FTP servers.
Though there's nothing that prevents you from initiating a normal (full) download and forcefully break it as soon you get the amount of data you need.
All you need to do is to close the data transfer connection. This is basically what all FTP clients do, when an end user decides to abort the transfer.
This approach might result in few error messages in an FTP server log.
If you can use an SFTP protocol, then it's easy. The SFTP supports this natively.

How to refresh Panic Transmit file list?

I like the Panic Transmit client for FTP and SFTP, but have lost work a couple of times because the file list is cached and can't be completly refreshed easily.
The Refresh option in the View menu only refreshes the current directory, and doesn't do the subdirectories.
I've contacted Panic about this and got a response that it's the way it works, and they would like to change it but not in this release. I've tried a couple of other FTP clients and find them lacking, eg. Fetch only shows the remote side and uses the Finder for the local side, this gets confusing quite quickly.
Does anyone know where Transmit keeps the cache of the file list so I can delete it and get a full refresh?
If not, it's back to the future with SCP, RSYNC and command line FTP.
I found a crude workaround for this. Transmit keeps the cache in memory, so if you quit the application it is cleared. I just make a habit of always using quit from the dock before any usage that requires up to date timestamps.

Client-server synchronization

I found a nice answer of S.Lott about what I've been searching for:
Client-server synchronization pattern / algorithm?
But my question is now, what if the client has a wrong time?
Here's my problem:
Let's say the time of the client is 1 hour behind the servers, then the client changes a file, so the last write time is now 1 hour behind the servers. When the user starts his program which synchronizes the file, the server says to the changed file: "Oh, that file you have there is 1 hour older than mine, so let's replace it", but that's wrong, because the users file is actually newer, so it should be uploaded to the server.
I need a system that checks if the file is newer on server or on the client, and that doesn't work if the time is wrong or different.
Any ideas?
By the way, I am trying to write a cloud program.
If you're resolving conflicts manually (which would make sense for most applications), this can probably be done better with versioning rather than timestamps. When a client modifies a file, set a flag. When synchronizing, check the flag and versions.
If the client flag is set and the client and server versions are the same, send the client file to the server.
If the client flag is not set and the server version is newer, send the server file to the client.
If the client flag is set and the server version is newer, a conflict occurred and should be resolved.
The versions are per-file and should be sent along with the files.
Reset all client flags after synchronization.
This 'flag' can just be a check whether the last modified time on the file is different from the time that file was received from the server (we can store this time separately right after getting the file from the server).
Alternatively, you could sync the time.
Here's one possible solution:
When receiving files from the server, first get the current time from the server, then offset the timestamp of each file received on the client side by the difference between the server and client time. When sending files to the server, you can do something similar by offsetting by the client time.
But this seems more complex than necessary.

Resources