Error 223 when opening a file in a OneDrive - winapi

For my backup tool I tried to load a file in an OneDrive folder (mapped as a Windows drive), but trying to open a file from this drive results in error 223:
auto hX = CreateFile(L"O:\\BACKUP\\1.dat", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
results in INVALID_HANDLE_VALUE and GetLastError() returns 223:
The file size exceeds the limit allowed and cannot be saved.
This is an > 1GB file.
Is there a way to get a handle without actually downloading the entire file, but only download on demand?

Is there a way to get a handle without actually downloading the entire file, but only download on demand?
If it means for one file, the answer is no as Jonathan mentioned. However it should work if you want to implement the tools to work with OneDrive Files on-demand.
When you use CreateFile to open a file which is not sync to the computer, it will download the scream from OneDrive automatically. The error about The file size exceeds the limit allowed and cannot be saved occurred when there is a setting on your client computer limited the file size when the files downloaded from online. You can refer this settings from link below or test this feature with a small size file which is online view only.
https://answers.microsoft.com/en-us/ie/forum/all/error-0x800700df-the-file-size-exceeds-the-limit/d208bba6-920c-4639-bd45-f345f462934f?auth=1

Related

How Dropbox sync works

I'm asking this question out of curiosity.
When I copy 1 GB file into Dropbox server, it automatically updates in my local machine Dropbox folder but in file property it shows size as 1 GB and size on disk as 0, once I double click on the file it starts downloading and size on disk will set as 1 GB.
How are they handling the file metadata. are they setting file property or showing thumbnail which looks like a file or are they following their own filesystem like FUSE.I would like to know more about it. what is the logic behind this ?

Windows api for locking a file

When we open a word or an excel file. It gets exclusive lock, so if somebody tries to edit and save the changes, he gets an error stating "file is already used by some other user", he only has the read-only copy of that document which is created in temp folder. So can somebody tell me which api is used by windows for locking a file on open.
See dwShareMode param from CreateFile API. Can give you the file or device cannot shared or not opened until the handle to the file or device is closed. Also see LockFile.

Windows Explorer and Reparse Point Files: keep Explorer from opening my files

I've implemented a user mode program and a Windows file system minifilter that creates a skeleton view of users files for a remote file storage system. It maps the remote files to the local drive. The user mode program creates a reparse tag for each file on the remote system. When a create request (e.g., CreateFile for read) is detected, the minifilter asks the user mode program to download the file. This should only happen when a program wants to open the file for viewing or editing.
But, I'm finding that Windows Explorer is triggering my files to download. I'd like to prevent the Explorer File windows and File Open/Save dialogs from
triggering downloads. And, I also want to display the file thumbnails and file
size.
[Update: I've found I can use Windows sparse files to show my remote
file size in Explorer. ]
Therefore, I have also implemented a Shell Extension, IThumbnailProvider, that downloads a rendition of the file. This provides the file thumbnails.
For my testing, I've registered the IThumbnailProvider for all files (*) and for .jpg files.
I'm seeing two interesting behaviors using a combination of Process Monitor and DebugView (both from SysInternals):
1. If I make my minifilter reject requests to open the file from Explorer, then my IThumbnailProvider is invoked.
2. If I permit open requests from Explorer, I see thumbcache.dll in the call stack trying to open the file and my IThumbnailProvider is not called. It appears that the default thumbnail provider reads the downloaded file and creates the thumbnail.
I must be missing something.
Update: if I use InitializeWithStream instead of InitializeWithFile, it appears my handler is invoked. But, that also triggers a download of the file.
There are many shell extension types which can access to your files. Icon handler can read file to create icon, Info tip handler can read file to create text hint, Data object handler can read file to create clipboard data and so on.
Questions from developer with the same problem: first and second. Solution was to create namespace shell extension. NSE can control all access to your files.

Delete a file opened for exclusive access in the same process

My windows program receives information from another program via directory/file interface.
That is the other program drops files into a special directory. My program periodically scans the directory, finds the files, processes and then deletes them.
I use CreateFile() function to open such files. To ensure that the other program has finished writing to the file and closed it, I set the dwShareMode parameter to 0. If CreateFile fails with a sharing error I just skip the file until the next itteration.
The problem is that DeleteFile() fails with the ERROR_SHARING_VIOLATION error while the file is opened by my program.
I could close the file before deleteing it, but I would like to avoid the possibility of some other program opening the file just before I delete the file.
I use this code to open files
CreateFile(filePath,DELETE|FILE_READ_DATA,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)
Is it possible to achieve what I want: open the file exclusively an then delete it, so that no other program can interfere between openning and deleteting the file.
FILE_FLAG_DELETE_ON_CLOSE is probably what are you looking for. From MSDN
*FILE_FLAG_DELETE_ON_CLOSE
0x04000000 -
The file is to be deleted immediately after all of its handles are closed, which includes the specified handle and any other open or duplicated handles.
If there are existing open handles to a file, the call fails unless they were all opened with the FILE_SHARE_DELETE share mode.
Subsequent open requests for the file fail, unless the FILE_SHARE_DELETE share mode is specified.*
EDIT: added an example...
So, in you case you should:
HANDLE hFile = ::CreateFile(filePath,
DELETE|FILE_READ_DATA,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_DELETE_ON_CLOSE,
NULL);
//use the file...
::CloseHandle(hFile); //the file gets deleted when the handle is closed
Pass in FILE_SHARE_DELETE for dwShareMode. Note that this will still allow other applications (as well as your own) to call DeleteFile() while you are reading the file, but according to the documentation of DeleteFile() it won't be deleted until you call CloseHandle() to close your read handle.
The DeleteFile function marks a file for deletion on close. Therefore,
the file deletion does not occur until the last handle to the file is
closed. Subsequent calls to CreateFile to open the file fail with
ERROR_ACCESS_DENIED.
Other applications will not be able to read or write the file as long as you don't specify FILE_SHARE_READ or FILE_SHARE_WRITE respectively. Although with FILE_SHARE_DELETE then can move the file, but that would be it.

How can CreateFile fail with FILE_SHARE_READ and succeed with FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE?

Try it yourself:
Create an XLS file, open it in Excel.
Open sysinternals Process Monitor, and watch what happens while you make a copy of your XLS file in the explorer (just hit ctrl-c ctrl-v).
Two calls to ::CreateProcess in a row. First call asks for read permissions, and gets Access denied. Second call asks for read plus write plus delete and passes.
Is that normal?
If you open a file with FILE_SHARE_READ you're saying you're willing to share access to this file, but only for reads.
If you open with all the flags, you're willing to share access also for writes/delete.
FILE_SHARE_READ is more restrictive than FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE
If some other process (excel) has this file opened for e.g. write (and it has the sharing flags set), the only way you can access it is to accept sharing it for write.
You have to use compatible sharing modes. If Excel opens the file with FILE_SHARE_READ | FILE_SHARE_WRITE then subsequent attempts to open the file must use at least those same flags. Specifically from the MSDN documentation on CreateFile:
You cannot request a sharing mode that conflicts with the access mode that is specified in an existing request that has an open handle. CreateFile would fail and the GetLastError function would return ERROR_SHARING_VIOLATION.

Resources