How can I lock a file in windows to only current thread (no other threads from same process and no other processes) can access (read/write) the file?
If it is possible please tell me some fcntl-like solution (solution which locks file having its descriptor). But in any case other solutions are welcome too.
In Windows, you can open a file with exclusive access with the API function CreateFile and specifying 0 as the share mode. More details at this MSDN link, and this MSDN link.
Use the WinAPI call LockFile, Here is a example of its use. However this will only protect you from other processes from touching your file, it still lets other threads in the same process use the file.
EDIT:
I did not see this was C++ sorry, I only know the inter thread c# solution, however that MSDN link can at least get you started on preventing other processes from touching your file.
Related
I am writing my own version of DebugView using this article:
https://www.codeproject.com/Articles/23776/Mechanism-of-OutputDebugString
as a starting point.
According to the article OutputDebugString() first locks a mutex named "DBWinMutex" and the writes to a 4096 bytes area of shared memory named "DBWIN_BUFFER" and then signals an event named "DBWIN_DATA_READY".
The code seems to be working fine. However how can I make sure that it will work for all versions of Window?
What prevents Microsoft from e.g. renaming the shared memory area to "DBWIN_BUFFER2"?
I am looking for some offical documentation of the DBWIN mechanism and ideally also a header file with defines of these string constants.
This is asking about implementation details, that are deliberately not publicly documented. The documented way to receive data from a call to OutputDebugString is to call WaitForDebugEventEx and evaluate OUTPUT_DEBUG_STRING_INFO DEBUG_EVENTs.
The documentation comes with a full sample on how to write the debugger's main loop.
Given I have a list of all file handles of all processes, how could I find out which of these handles are actually locking a file?
From what I understand I could simply try to open the files and try to get all the permissions and if something goes wrong I'd know it is locked. But that sound extremely inefficient. I mean I already have the handles is there no way to check which permissions the handles have?
Preferably I'd like to see a solution that works on Windows XP and above.
I already searched through the GetFileInformationByHandleEx function, but I couldn't find anything about access permissions. :/
Edit:
I don't need real-time information on the file lock. The files that I'm planning to work on will either be locked until certain applications are closed or not be locked at all.
This question is a duplicate of Win32 files locked for reading: how to find out who's locking them.
Also, Hans Passant's commentary is correct: querying the locked state of any Win32 file gives stale information. Disregarding this warning will cause hard-to-find bugs.
If you control all bits of code that you think will access the files, it's better to use a named pipe for interprocess communication, instead of querying locked files.
You can use NtQueryObject API to get information about the handle including the following:
ULONG Attributes;
ACCESS_MASK GrantedAccess;
Or you can access the same information using NtQueryInformationFile using FileModeInformation and FileAccessInformation values for FileInformationClass parameter.
I'd like to lock a couple of files to be only used by my process, denying any other application access to these files while my program is running. Of course I know that I can get exclusive access to a file using Createfile, but my application works differently, I read a bunch of filenames froma config, and process these files with a Lib linked to my application, i.e. one of the functions in my lib accesses the files, but I don't get a filoehandle or something similar in return.
So what I want to acchieve is that while my app is processing these files, no other application can modify them. Is this somehow possible? I am developing using MFC in Visual Studio 8.
I've never used them, but LockFile/LockFileEx docs say: Locks the specified file for exclusive access by the calling process.
You need cooperation from the OS, because that's the only way to influence other processes.
The OS requires that you use handles to refer to files. It's really the only practical way for the OS; using pathnames would be far too complex. So, you will need to call CreateFile. At that point, just request exclusive access.
Why doens't the CreateFile()'s exclusive flag achieve this? It looks like you don't need anything fancy. If your library opens the file with CFile::shareDenyRead and CFile::shareDenyWrite, no other process can read your files as long as they are open by your library.
What you're asking can't be done.
Because exclusive access is granted per handle, not per process, if you open a file with exclusive access once, every subsequent attempt to open it will fail, even if it is from the same process. Exclusive access here means your handle is the only valid one, not that only your process can access it.
So even if you lock a file, your lib won't be able to open it, so it's useless to you. The only way is to lock a file and pass the handle to your lib, which you can't do because your lib wants a filename. Likewise you can't lock the file once it's open by the lib because it won't give you the handle. If you don't have access to the source code of the lib, you're stuck.
You possibly could try something with user permissions, having you're process run from it's own user account and changing the ownership of the files you're about to modify and then changing it back when you're done.
This is something that's been bothering me a while and there just has to be a solution to this. Every time I call ShellExecute to open an external file (be it a document, executable or a URL) this causes a very long lockup in my program before ShellExecute spawns the new process and returns. Does anyone know how to solve or work around this?
EDIT: And as the tags might indicate, this is on Win32 using C++.
I don't know what is causing it, but Mark Russinovich (of sysinternal's fame) has a really great blog where he explains how to debug these kinds of things. A good one to look at for you would be The Case of the Delayed Windows Vista File Open Dialogs, where he debugged a similar issue using only process explorer (it turned out to be a problem accessing the domain). You can of course do similar things using a regular windows debugger.
You problem is probably not the same as his, but using these techniques may help you get closer to the source of the problem. I suggest invoking the CreateProcess call and then capturing a few stack traces and seeing where it appears to be hung.
The Case of the Process Startup Delays might be even more relevant for you.
Are you multithreaded?
I've seen issues with opening files with ShellExecute. Not executables, but files associated an application - usually MS Office. Applications that used DDE to open their files did some of broadcast of a message to all threads in all (well, I don't know if it was all...) programs. Since I wasn't pumping messages in worker threads in my application I'd hang the shell (and the opening of the file) for some time. It eventually timed out waiting for me to process the message and the application would launch and open the file.
I recall using PeekMessage in a loop to just remove messages in the queue for that worker thread. I always assumed there was a way to avoid this in another way, maybe create the thread differently as to never be the target of messages?
Update
It must have not just been any thread that was doing this but one servicing a window. Raymond (link 1) knows all (link 2). I bet either CoInitialize (single threaded apartment) or something in MFC created a hidden window for the thread.
I want to execute a certain batch file and redirect its console output to a text control in visual c++ or redirect the console output at the same time the logs/echo are showing.
Basically, you have to make the run process to write to a pipe, and to read the output of this pipe.
[EDIT] I know how SciTE does that (you can take a look at the source: win32/SciTEWin.cxx, ExecuteOne function), I searched a slightly more generic way, found How to spawn console processes with redirected standard handles from Microsoft itself.
If you seach CreatePipe PeekNamedPipe CreateProcess keyword, for example, you might find other examples.
Another option is to use Boost.Process (Boost.Process is not (yet) an official Boost C++ library. It must be downloaded and installed separately).
The example "Child.4 - Reading from a child using asynchronous I/O" shows how to redirect the output of the child process into a C++ stream (and later access the content).
Example "Child.4 - Reading from a child using asynchronous I/O" show how to use Boost.Process togehter with Boost.Asio to access the childs I/O asynchronous.
The advantages of this method is, that Boost.Process supports the Windows API and POSIX API.
If elegance is not a priority then a really simple solution might be to redirect the output to a file, and then read in the file contents.