Aborting synchronous ReadDirectoryChangesW - winapi

I'm using the synchrounous flavor of ReadDirectoryChangesW in a thread. Everything works perfectly well.
But I'm unable to terminate the thread otherwise than calling TerminateThread from my main thread, because if there is no activity in the monitored directory, ReadDirectoryChangesW is waiting forever.
The solution with TerminateThread works, but this is kind of dirty.
Another solution would be to create a dummy file in the monitored directory which will unblock ReadDirectoryChangesW, but this is just another hack.
So is there a way to unblock/abort ReadDirectoryChangesW properly ?

You could switch to using it with a completion routine and immediately after the call to ReadDirectoryChangesW() call a wait function which puts you into an alertable wait state and also waits on an event which you use to abort the wait...

If you open the handle with FILE_SYNCHRONOUS_IO_ALERT then it is possible to use the undocumented NtAlertThread to send a signal to stop the wait.

Related

Killing a process that is hanging on disk IO

I've got an SSD that is failing. Some of its data can't be read anymore.
I would like to know which files are affected.
I've created some small program that uses regular functions (CreateFile, ReadFile) to read files.
The program has some watchdog thread that monitors the thread that issues the IO functions. If they take too long, the thread marks somewhere the file is damaged and tries to kill the IO thread and the process.
My issue is using TerminateThread and TerminateProcess does not kill the thread/process. It hangs there, forever, until I log out.
Trying to kill using TaskManager also fails, of course (it used to use NtTerminateProcess, I don't know what it does nowadays).
Does anyone know a way that would kill my process?
According to the Doc: TerminateProcess function
This function stops execution of all threads within the process and
requests cancellation of all pending I/O. The terminated process
cannot exit until all pending I/O has been completed or canceled. When
a process terminates, its kernel object is not destroyed until all
processes that have open handles to the process have released those
handles.
When a process terminates itself, TerminateProcess stops execution of
the calling thread and does not return. Otherwise, TerminateProcess is
asynchronous; it initiates termination and returns immediately. If you
need to be sure the process has terminated, call the
WaitForSingleObject function with a handle to the process.
I suggest you could try to use Job Objects.

Does DebugActiveProcessStop close handles?

According to the documentation, ContinueDebugEvent will close handles after EXIT_THREAD_DEBUG_EVENT and EXIT_PROCESS_DEBUG_EVENT.
What happens to those handles in the following case:
DebugSetProcessKillOnExit(FALSE); // Keep the process running after stopping the debugger.
DebugActiveProcessStop(dwProcessId);
The process and threads will still be running, and the documentation doesn't mention anything about handles. Can I assume that they will be closed for me?
yes, DebugActiveProcessStop call CloseAllProcessHandles before do actual stop debugging via DbgUiStopDebugging call. the CloseAllProcessHandles close all opened thread and process handles. it list stored in thread TEB - this mean that call must be done only from the same thread which call other debug api (such WaitForDebugEvent). unfortunately i also not view confirmation of this in documentation, only research. this screenshot from win10

Detach debugger(unknown) from process?

I am trying to attach debugger(windbg,ollydbg) to running process but there's an error saying Debugger is already attached then how can i detach that unknown debugger from that process?
Process includes multi thread, one thread can be attached to debugger and other can't.
The process might be spawning a second process which attaches to the first process for debugging using DebugActiveProcess() in order to prevent people from debugging the first process. Keep in mind that a process cannot debug itself using this method, so a second process must be spawned to do this.
Things you could try:
Use any sort of process monitor or even task manager to figure out what process the first process spawns
Inject code into the second process to call DebugActiveProcessStop() to detach it from the first process
Hook DebugActiveProcess() (kernel32.DebugActiveProcess, ntdll.ZwDebugActiveProcess, or in kernelmode) and redirect it to attach to a different dummy process
Kill the second process
Prevent the second process from getting a handle to the first process with the needed permissions - DebugActiveProcess() will then fail
Use alternative debugging methods (Cheat engine with VEH debugging for example) that don't use the normal debugging API's and therefore bypass this problem

Catch App Terminate from LaunchDeamon

I've got a Cocoa foundation tool that I run as a LaunchDeamon. When the app is terminated by the system, either by a reboot or shutdown (or even launchctl unload), is there a way I can capture this event so that I can perform some finalizing functions?
All the cases you're discussing send SIGTERM to the process. You want to add a signal handler for that. See the man pages for signal and sigaction. Read the warnings carefully. Only certain functions are legal to call during a signal handler (and in principle you should never allocate heap memory). Generally it's best to just use the handler to set a flag that tells your main thread to terminate.
You may also want to look at PreLoginAgents for an example of how to handle SIGTERM using the run loop, if you're using a run loop.
See Terminating Processes in the Daemons and Services Programming Guide for full details on what signals will be sent to your process.
All NSObject subclasses call a method before dying: - finalize. There is also NSSetUncaughtExceptionHandler for dealing with crashes.

How to keep thread on processor till an event happens?

I am spawning few threads inside ioctl call to my driver. I am also assigning kernel affinity to my driver. I want to ensure one of the thread does not get scheduled out till a particular event is flagged by the other thread. Is there any way to not allow windows scheduler to context out my thread. Using _disable() may hang the system as event may take couple of seconds.
Environment is windows 7,64bit
Thanks,
What you are probably after is a spin lock. However this is probably a bad idea unless you can guarantee that your driver/application is always run on a multi-processor system, even then it is still very bad practice. On a single processor system if a thread spin locks then the other thread signalling the spin locked thread will never be scheduled and so can't signal your event. Spin locks are meant to be used sparingly and only when the lock is for a very short time, never a couple of seconds.
It sounds like you need to use an event or other signally mechanism to synchronise your threads and let the windows scheduler do its job. If you need to respond to an event very quickly then interrupts or a Deferred Procedure Call (DPC) could be used instead.

Resources