Export a .sqlite file in C/C++ (on windows) - c++

It is possible to move a .sqlite file somewhere while not corrupting it in C or C++?
Somewhere could be another folder or something.
If so could you give me some tips/pointers.

Yes, of course. It is a regular file that can be moved around just like any other file.
The sqlite engine itself will make sure that it does not corrupt. Either it is in a clean state, or locked when being written to (with journaling).
One thing to remember that you should not use the database file on filesystems that do not have reliable locking, e.g. on network disks.

Well, it depends a little. It is just a regular file that (assuming nothing is connected to it, writing to it at the time) can be copied without problem. Welcome to the world of open source systems where things really are that simple (ie you don't need to update the registry, a config file or two, reapply installer settings or anything like that).
However, things are tricky if something is using the file. When an app opens a sqlite file it can tell the OS to lock it - the default is open with exclusive access for the opening app (using a certain flag). In such a case, you will not be able to move the file as the OS will prevent it until the app that has it locked is stopped.

Related

Is it safe enough to store a file in the TEMP directory

Is it safe enough to store a file in the %TEMP% directory via GetTempPath, GetTempPath and CreateFile for more than two hours? Is there any guarantees that this file won't be deleted earlier?
Thanks in advance.
A file you create in the TEMP directory must be created with the CreateFile's FILE_FLAG_DELETE_ON_CLOSE option. This ensures that the file will always be cleaned-up and you cannot spray garbage files, even if your program crashes before it has a chance to delete the file again.
This option then also inevitably forces you to do the Right Thing, keeping the file opened while you are using it. Which in turn prevents anybody from the deleting the file, even if they use a sledge-hammer.
Lots of programs don't follow this advice and a user's TEMP directory tends to be a big olde mess, forcing the user to clean it up manually once in a while. A built-in feature of Windows, he'll use the "Disk Cleanup" applet. The kind of scenario where you will lose the file if you don't follow this advice. Best to use %AppData% instead.
There are no guarantees. This folder is usually not cleared except the user starts any cleanup.
But everyone can delete files here. And it is wise to do that on a regular base
To prevent the file from being deleted, you can keep a handle open (assuming the application is running the whole time) and do not specify FILE_SHARE_DELETE (and, if applicable, neither FILE_SHARE_WRITE).
Alternative:
Use a path in %APPDATA% or %PROGRAMDATA% that you clear yourself regulary, or let the user specify a path.
In addition, you could register a scheduled task to clean the folder regulary.
If you do not want that another process can delete your files, just keep them open with a share mode of FILE_SHARE_READ | FILE_SHARE_WRITE. That way any attempt to delete them will fail, but any other process will be able to read or write them.
BTW : this is not related with the files living in %TEMP% folder.
If you cannot have a process to keep them open all the time, you must rely on other processes (and other users) on your system not doing anything ...

Syncing independent applications. (How to check if a file was modified by another program on runtime)

It is easier to explain with example.
When 2 text editors edit the same text file in the same time, when one editor saves the file, the other one understands that it was modified and asks to do smth.
How is it possible to get a signal that a file was modified outside the program?
I am working with c++ (though I think it isn't important) and on linux. (solution for windows would be good too)
ISO-C++ does not offer this functionality, so you have to stick with what the operating system provides.
On Linux that would be inotify, on Windows you would use directory change notifications.
① Check the timestamp of the file as close as possible before writing. If it is not what it was when you last opened this file for reading, then beware!
② You can build a checksum of the file and compare this to one you built earlier.
③ Register to a system service which informs you about file activities. This depends on the goodwill of the OS you are using; if this notification service isn't working properly, your stuff will fail. On Linux have a look at Inotify.

How can I ensure my process never locks another process out of a file?

I have a Windows process that runs in the background and periodically backs up files. The backup is done by uploading the file to a server.
During the backup, I don't want to lock any other application out of writing to or reading from the file; if another applications wants to change the file, I should stop the upload and close the file.
Share mode is useless here; even though I'm sharing all access to the file being read, if the other process attempts to open it for writing without sharing read, it will be locked out of the file.
Is it possible to accomplish this on Windows, without writing a driver?
You may be interested in Volume Shadow Copy.
You certainly could copy the file and then check that the original and copy are identical (thus representing a consistent snapshot) prior to uploading to the server.
According to this MSDN page, if using NTFS, you should be able to lock the file inside a transaction of yours, while uploading the file to a server. This will ensure your view of the file does not change, even if the file has been changed externally.

How to create virtual file system that file path can be accessed same as disk

I need to create FileSystem type of thing in memory or on disk, which can be accessed same as file on disk, which path is can be used in function like fopen(),etc.
Details:
I am using AddFontResourceEx function to load font in application. Since this function require file path so that file need to present on disk. But I've requirement, that the user cannot access/see the font file.
I tried AddFontMemResourceEx function, but the loaded font is not enumable so that user cannot see the font in the application. Also I tried with some library which create VFS, but they work like database, i.e you can create file/directory and access them. But cannot use their file path in AddFontResourceEx or any other function.
Is there exist some way by which I can create a Virtual FileSystem in memory or on disk which can be accessible through my application and I can write/read file on this virtual filesystem created and it's file path can be used by AddFontResourceEx function.
It can't really work. Yes, you can add a "virtual" file system. But either it's visible to user X or it isn't. Access Control on Windows works on a per-user base, not a per-program base. So, if user X can see the font in application A, he can also see it in application B - even if B is Explorer.EXE.
If the user is an administrator, you can't really prevent them from seeing the font file if they're determined enough. They could, for example, reverse engineer your program to figure out how you're generating the file and repeat the process by hand to make their own copy. Or (even if you could somehow tie the file permissions to your process) they could insert their own code into your process to retrieve the file, or to retrieve the font information directly from memory.
If it's good enough to make it difficult for them to see the font file, you could try this:
Create a directory in the temp folder, with write-only permission for the current user and no permissions for anyone else.
Create a sub-directory with a long, complex, cryptographically random name, and with full permission for the current user. (The name should be different each time.)
Write the font file to the sub-directory and load it.
Delete the font file and remove both directories.
The entire process should take only a fraction of a second, which should make it somewhat difficult for the user to override the permissions and retrieve the file. If they use a debugger to single-step through the program then I guess you're out of luck, but as I already pointed out, nothing's going to stop everyone.
Another option, presumably, would be to just use AddFontMemResourceEx and put up with the fact that the font isn't then enumerable. You'd just need to change your code so that wherever it enumerates fonts it adds your font(s) to the list manually.
If you didn't get the right answer, maybe you didn't ask the right question
Your post title mentions "virtual filesystem", but. later, you mention "accesing a font".
"Virtual Filesystems" its an ambiguos term used in several ways.
One common case, means adding devices or networks to an O.S.
In your case, seems like accesing from a an application.
There are several ways ( "libraries" ) to emulate or work with a filesystem.
Some of them work independent of the real filesystem. You work with them, save data in those "virtual" folders & files, and copy data from the real and the virtual one.
Some of them work, as a extension layer, between the real filesystem, and the programming filesystem.
Example: I worked with an application, that required temporally fast I.O. access. Found a library, that when you want to create a folder or save a file in the real filesystem, was done.
Additionally, I could add "virtual drives" that where stored in memory, but, accessed with file system operations. When the application finished, the "hard drives" and their data where erased from memory.
Its seems that your case is similar to my example.
What do you want a "virtual filesystem" library for ?
I have seen onb the web, several libraries, for C++, open source, freeware, and commercial.
It depends what do you want to do, to find out, which library its the better for your case.
Good Luck

C++ : Opening a file in non exclusive mode

I have to develop an application which parses a log file and sends specific data to a server. It has to run on both Linux and Windows.
The problem appears when I want to test the log rolling system (which appends .1 to the name of the creates a new one with the same name). On Windows (haven't tested yet on Linux) I can't rename a file that I have opened with std::ifstream() (exclusive access?) even if I open it in "input mode" (ios::in).
Is there a cross-platform way to open file in a non-exclusive way?
Is there a way to open file in a non-exclusive way,
Yes, using Win32, passing the various FILE_SHARE_Xxxx flags to CreateFile.
is it cross platform?
No, it requires platform-specific code.
Due to annoying backwards compatibility concerns (DOS applications, being single-tasking, assume that nothing can delete a file out from under them, i.e. that they can fclose() and then fopen() without anything going amiss; Win16 preserved this assumption to make porting DOS applications easier, Win32 preserved this assumption to make porting Win16 applications easier, and it's awful), Windows defaults to opening files exclusively.
The underlying OS infrastructure supports deleting/renaming open files (although I believe it does have the restriction that memory-mapped files cannot be deleted, which I think isn't a restriction found on *nix), but the default opening semantics do not.
C++ has no notion of any of this; the C++ operating environment is much the same as the DOS operating environment--no other applications running concurrently, so no need to control file sharing.
It's not the reading operation that's requiring the exclusive mode, it's the rename, because this is essentially the same as moving the file to a new location.
I'm not sure but I don't think this can be done. Try copying the file instead, and later delete/replace the old file when it is no longer read.
Win32 filesystem semantics require that a file you rename not be open (in any mode) at the time you do the rename. You will need to close the file, rename it, and then create the new log file.
Unix filesystem semantics allow you to rename a file that's open because the filename is just a pointer to the inode.
If you are only reading from the file I know it can be done with windows api CreateFile. Just specify FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE as the input to dwShareMode.
Unfortunally this is not crossplatform. But there might be something similar for Linux.
See msdn for more info on CreateFile.
EDIT: Just a quick note about Greg Hewgill comment. I've just tested with the FILE_SHARE* stuff (too be 100% sure). And it is possible to both delete and rename files in windows if you open read only and specify the FILE_SHARE* parameters.
I'd make sure you don't keep files open. This leads to weird stuff if your app crashes for example.
What I'd do:
Abstract (reading / writing / rolling over to a new file) into one class, and arrange closing of the file when you want to roll over to a new one in that class. (this is the neatest way, and since you already have the roll-over code you're already halfway there.)
If you must have multiple read/write access points, need all features of fstreams and don't want to write that complete a wrapper then the only cross platform solution I can think of is to always close the file when you don't need it, and have the roll-over code try to acquire exclusive access to the file a few times when it needs to roll-over before giving up.