Cant find SetConsoleCtrlHandler in Kernel32

24 views
Skip to first unread message

Cyber Avater

unread,
Dec 28, 2023, 11:53:16 AM12/28/23
to Java Native Access
I can make my own kernel32
native boolean SetConsoleCtrlHandler(StdCallLibrary.StdCallCallback handler, boolean add);
but it seems I cannot use 2 different Kernel32 instances (one by you guys and one by me) at the same time.

Why SetConsoleCtrlHandler was not added by you guys?
Thanks in advance.

Matthias Bläsing

unread,
Dec 28, 2023, 5:08:06 PM12/28/23
to jna-...@googlegroups.com
Am Donnerstag, dem 28.12.2023 um 08:53 -0800 schrieb Cyber Avater:
I can make my own kernel32
native boolean SetConsoleCtrlHandler(StdCallLibrary.StdCallCallback handler, boolean add);
but it seems I cannot use 2 different Kernel32 instances (one by you guys and one by me) at the same time.

Sure you can, you can name your instance Kernel32Ext or use a different package. There were multiple discussions here, where people extended bindings from JNA into their own classes, without problems.

Why SetConsoleCtrlHandler was not added by you guys?

Because "you" does not exist. I landed here because I needed a library, that gave me enough utilities to call into COM objects and not stay in my way. After that was done I stayed and ensured, that the project kept being buildable. The common idiom is: you find a problem in JNA, that affects you, you fix it and contribute the fix back upstream. Next time, you will benefit from a bugfix someone else donated. Consider it payment for the invest you did not have to make when you started using JNA.

So: Feel free to prepare a PR to add the binding to JNA. When you do it, the things people (most probably me) will look at:

- is the binding correct (i.e. will it work with win32.ascii set to true and false)?
- is there at least a basic test?
- is there documentation?
- does the PR pass basic scruteny: Is there a valid author address and a valid author name?

If that all holds true, I don't see a reason not to merge.

Greetings

Matthias

Cyber Avater

unread,
Dec 28, 2023, 11:08:10 PM12/28/23
to Java Native Access

> Sure you can, you can name your instance Kernel32Ext or use a different package.

I was having an issue with mixing ntdl given by the library and my custom one (implements undocumented), then I ended up coping the portion from the library and it worked as expected. That's why I thought I couldn't use both at once.


> Feel free to prepare a PR

Possible, but it would be better if you do it, (I'm just not as experienced as you)

here is my basic test which seems to be working.
I'll also soon send the final code where I intend to use it.
interface Kernel32Ext : StdCallLibrary {

fun SetConsoleCtrlHandler(
// handler: StdCallLibrary.StdCallCallback?,
handler: HandlerRoutine?,
add: Boolean,
): Boolean

interface HandlerRoutine : StdCallLibrary.StdCallCallback {
fun callback(ctrlType: Int): Boolean
}
companion object {
val INSTANCE = Native.load(
"kernel32", Kernel32Ext::class.java, W32APIOptions.DEFAULT_OPTIONS
)
}

}


fun main() {
val kernel32Ext = Kernel32Ext.INSTANCE

val handler = object : Kernel32Ext.HandlerRoutine {
override fun callback(ctrlType: Int): Boolean {
return when (ctrlType) {
-> {
println("CTRL_C_EVENT"); true
}

-> {
println("CTRL_BREAK_EVENT"); true
}

else -> false
}
}
}

if (kernel32Ext.SetConsoleCtrlHandler(handler, true)) {
println("Handler set.")
else {
println("Failed to set handler.")
}

}

Cyber Avater

unread,
Dec 29, 2023, 8:08:37 AM12/29/23
to Java Native Access

Okay, it seems mixing 2 different instances works. (I assume previously it did work because the UNICODE_STRING was removed from the library and a version mismatch in the module caused it)

Finally I was able to use my own implementation in my code

fun sendSignal(pid: Int, signal: Signal) {
//Freeing ourself from other console before attaching a new one (At most 1 console can be attached).
// https://gist.github.com/rdp/f51fb274d69c5c31b6be#file-send_ctrl_c-c-L41
kernel32.FreeConsole()

val attachSuccessful = Kernel32.INSTANCE.AttachConsole(pid)
if (!attachSuccessful) {
throw RuntimeException("Kernel32 AttachConsole: ${lastErrorMessage()}")
}

// Disable Ctrl-C handling for our program
val isConsoleHandlerSet = kernel32Ext.SetConsoleCtrlHandler(null, true)
if (!isConsoleHandlerSet)

{
throw RuntimeException("Kernel32 SetConsoleCtrlHandler: ${lastErrorMessage()}")
}

kernel32.GenerateConsoleCtrlEvent(signal.eventCode, 0)

kernel32.FreeConsole()
//Re-enable Ctrl-C handling or any subsequently started
//programs will inherit the disabled state.
// kernel32Ext.SetConsoleCtrlHandler(null, false)

}
Thanks for helping out!
Reply all
Reply to author
Forward
0 new messages