Jump to content

Recommended Posts

Posted

I have been looking at DebugView++.

I just wondered if I could monitor debug messages directly using AutoIt, without any third party apps.

Posted
1 hour ago, TwoCanoe said:

monitor Windows Debug Messages

All of them ? Some of them ? One in particular ?

12 minutes ago, TwoCanoe said:

monitor debug messages directly using AutoIt, without any third party apps.

The kernel is the OS, the rest is 3rd party. Explorer.exe is 3rd party and you can replace it.

Look into taskScheduler and create a task, ..on trigger: "When a specific event is logged", then choose "Log", "Source" and "Event ID". Make that call your script.

Unless you present better information, this is my best advise to not peek constantly.

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted

I currently only want to monitor one message/event: The keydown event for the 'Fn' key on my keyboard.

Like on most keyboards, the 'Fn' key is not recognised as a standard keyboard event.

The windows debug message is the only way I have found to monitor the Fn keydown event.

I have previously tried to setup a scheduled task, but resulted no output and no trigger. I'll have another look though.

Posted (edited)

Take a look at this:

Give it a try. Let me know if that did it.


Edit: I tried on my keyboard

Spoiler
Local $sOut, $Ret, $Ext
For $m = 1 To 10
Sleep(300)
ConsoleWrite(@CRLF & '--- --- --- --- --- --- --- ' & @CRLF)
For $n = 1 To 256
    $Ret = _IsPressed($n)
    $Ext = @extended
    If $Ret Or $Ext Then ConsoleWrite('0x' & Hex($n, 2) & @TAB & $Ret & @TAB & $Ext & @CRLF)
Next
Next

Func _IsPressed($sHexKey, $vDLL = "user32.dll")
;~     Local $aCall = DllCall($vDLL, "short", "GetAsyncKeyState", "int", "0x" & $sHexKey)
    Local $aCall = DllCall($vDLL, "short", "GetAsyncKeyState", "int", "0x" & Hex($sHexKey, 2))
    If @error Then Return SetError(@error, @extended, False)
    Return SetError(0, BitAND($aCall[0], 0x1), BitAND($aCall[0], 0x8000) <> 0)
EndFunc   ;==>_IsPressed

and no dice. The Fn key is a hardware thing that is handled by the keyboard to generate a keycode but by itself may not report anything depending on the hardware. If I was the hardware/firmware coder, I would not return anything unless an expected combination was done, but even on "Fn + Esc" to lock the Fn key, should not return anything.

Edited by argumentum
more

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted

https://learn.microsoft.com/en-us/previous-versions/windows/desktop/dnacc/guidelines-for-keyboard-user-interface-design
claims the same: No Fn keycode.

What is your environment ? ( CPU, keyboard, motherboard, the color of the wall and floor :P )
Because if you say you can do it via ... something, .. am curious :)

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted

Was just trying out your _Ispressed code, Arguementum. I was getting nowhere :)

The ‘Fn’ key function on most keyboards is one of those ‘propritery’ things. Even better is that ‘Fn’ function differs from manufacturer to from manufacturer. Some keyboards have ‘Fn’ functions are hardware only, built in to the keyboard.

I am using DebugView++ to view windows debug messages. See here:

https://github.com/CobaltFusion/DebugViewPP

There is also DebugView by Sysinternals (Microsoft).

I get a key-up and a key-down message for my keyboard (Razer keyboard).

 

Nine: I’ll have a look at you ‘hook’

Posted
Posted
9 minutes ago, TwoCanoe said:

I get a key-up and a key-down message for my keyboard (Razer keyboard).

ok, is a programable keyboard, like G1, G2, etc. keys.
And I bet that the debug is done by the keyboard's software installed on your PC. 

Looks like a fun project. Do they have an SDK ?, maybe you can go that route.

..I'll have to call it quits on this thread. I have homework and can not play :lol:
But do post the code when you find a way to it :)

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted

Sorry Nine, yeah it is the special “Fn” key.

The special Fn key does not appear in winuser.h, at least not in my case.

I have read that some manufactures have a fake Fn key, that may actually be something like Ctrl+F24. Unfortunately, not on my keyboard.

 

 

Agruementum, it probably is the software. I haven’t checked without the software, not yet.

I don’t know if there is a SDK for Razer devices. If there is, knowing Razer, access to the SDK will be many, many, $$$.

Running DebugView++ and applying a filter that only checks for the ‘Fn’ key down message will work, though I don’t know (yet) if I can run DebugView++ silently. I’m in no rush.

 

 

There is this, for anyone interested in windows debug messages:

https://learn.microsoft.com/en-gb/windows/win32/api/debugapi/nf-debugapi-outputdebugstringa?redirectedfrom=MSDN

Creating a function for OutputDebugString, is way, waaaaay over my head.

 

For now, thanks for the suggestions. I have homework too!

Posted (edited)

The Capture Debug Info UDF works well.

Here is my quick test script (modifed from Autoitter's DebugViewer.au3).

;----------------------------------------------------------------------------------
;
;   Requires:
;   DebugCapture.Dll in script directory
;   DebugCapture.au3 in script directory
;   
;   Note:
;   Run script in x86 only. DebugCapture.Dll was written in Visual Studio 6 (2008).
;
;----------------------------------------------------------------------------------


AutoItSetOption("MustDeclareVars", 1)
AutoItSetOption("TrayAutoPause",   0)


#include "DebugCapture.au3"


Global $bCapturing = False
Global $strData


; Razer keyboard 'Fn' keydown debug message
Global $strFilter1 = 'deviceModeChangedCallbackEvent:'      ; Event
Global $strFilter2 = 'json_event[{"isEnabled":true}]'       ; Keydown


HotKeySet("{Esc}", "StopCapture")


StartCapture()


While 1
    If $bCapturing Then
        $strData = _GetDebugOutput()
        If (Not @error) And ($strData <> "") Then
            ; Monitor DebugCapture output for required message (Filter)
            If StringInStr($strData, $strFilter1) And StringInStr($strData, $strFilter2) Then
                MsgBox(0, @ScriptName, "Fn Keydown")
            EndIf
        EndIf
    EndIf
    Sleep(10)
WEnd


Func StartCapture()
    If Not $bCapturing Then
        _StartDebugCapture()
        Switch @error
            Case 0
                $bCapturing = True
            Case 1
                MsgBox(16, @ScriptName, "Error loading DebugCapture.dll")
                Exit
            Case 2
                MsgBox(16, @ScriptName, "Initialization failed.")
                Exit
            Case 3
                MsgBox(64, @ScriptName, "Another debugger is already active.")
                Exit
        EndSwitch
    EndIf
EndFunc


Func StopCapture()
    If $bCapturing Then
        _StopDebugCapture()
        $bCapturing = False
        Exit
    EndIf
EndFunc


Thanks Folks!

Now, off to see if there is a 64-bit version of the DebugCapture.DLL available.

Edited by TwoCanoe
Fixed code
Posted
24 minutes ago, argumentum said:

There is no x64 available.

Yes so I found out. I've looked for an alternative DLL with similar capabilities, and x64. Have not found anything, yet.

25 minutes ago, argumentum said:

You're gonna have to compile it as x64 ( and share it here for us to have ) :D

I know less than nothing when it comes to C++! Gimme a few years and I see what I can do 🤔


If I find anything, like a compiled x64 DLL, I'll post it here!

Posted

Interesting usage of Security Descriptor/Attribute.  I wouldn't have thought of using it this way.  I need to dig a bit more to fully understand the intrinsic.

But in any case, at first glance, there is no need to have a DLL or C++ to perform the task.  All I have seen is simple calls to WinAPI.  Everything could be performed inside AutoIt (like I said at first glance). I will look into this later today and come back.

 

Posted
35 minutes ago, Nine said:

But in any case, at first glance, there is no need to have a DLL or C++ to perform the task.  All I have seen is simple calls to WinAPI.  Everything could be performed inside AutoIt (like I said at first glance).

Sounds good. Using an inbuilt API will always be the way to go.

Can't wait to see what you dig up :)

 

I’m currently figuring out some of the possibilities of using the script. So many I don't know where to start.

Posted (edited)

I got it working (I think).  Tested, both x86 and x64,  it gives same results.  I haven't put any error handling, as I wanted to see if it would work solely in AutoIt.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <StructureConstants.au3>
#include <WinAPIProc.au3>
#include <Array.au3>
#include <WinAPIFiles.au3>
#include <APIErrorsConstants.au3>

Global Const $SECURITY_DESCRIPTOR_REVISION = 1
Global $hEventBufferReady, $hEventDataReady, $hBuffer, $pDebugInfo, $bEnd

HotKeySet("{ESC}", Terminate)

Example()

Func Example()
  Local $iPID, $sOutput
  StartDebugCapture()
  Do
    $sOutput = GetDebugOutput()
    If $sOutput Then
      $iPID = @extended
      ConsoleWrite($iPID & @CRLF & $sOutput & @CRLF)
    EndIf
    Sleep(100)
  Until $bEnd
  StopDebugCapture()
EndFunc   ;==>Example

Func StartDebugCapture()
  Local $tSecurityDescriptor = DllStructCreate("byte;byte;word;ptr[4]")
  Local $tSecurityAttributes = DllStructCreate($tagSECURITY_ATTRIBUTES)
  $tSecurityAttributes.Length = DllStructGetSize($tSecurityAttributes)
  $tSecurityAttributes.Descriptor = DllStructGetPtr($tSecurityDescriptor)
  $tSecurityAttributes.InheritHandle = True
  Local $aCall = DllCall("advapi32.dll", "bool", "InitializeSecurityDescriptor", "struct*", $tSecurityDescriptor, "dword", $SECURITY_DESCRIPTOR_REVISION)
  $aCall = DllCall("advapi32.dll", "bool", "SetSecurityDescriptorDacl", "struct*", $tSecurityDescriptor, "bool", True, "ptr", 0, "bool", False)

  $hEventBufferReady = _WinAPI_CreateEvent($tSecurityAttributes, False, False, "DBWIN_BUFFER_READY")
  ;ConsoleWrite($hEventBufferReady & @CRLF)
  $hEventDataReady = _WinAPI_CreateEvent($tSecurityAttributes, False, False, "DBWIN_DATA_READY")
  ;ConsoleWrite($hEventDataReady & @CRLF)

  $hBuffer = _WinAPI_CreateFileMapping(-1, 4096, "DBWIN_BUFFER", $PAGE_READWRITE, $tSecurityAttributes)
  ;ConsoleWrite($hBuffer & @CRLF)
  $pDebugInfo = _WinAPI_MapViewOfFile($hBuffer, 0, 4096, $FILE_MAP_READ)
  ;ConsoleWrite($pDebugInfo & @CRLF)

  _WinAPI_SetEvent($hEventBufferReady)
EndFunc   ;==>StartDebugCapture

Func StopDebugCapture()
  _WinAPI_CloseHandle($hEventBufferReady)
  _WinAPI_CloseHandle($hEventDataReady)
  _WinAPI_UnmapViewOfFile($pDebugInfo)
  _WinAPI_CloseHandle($hBuffer)
EndFunc   ;==>StopDebugCapture

Func GetDebugOutput()
  If _WinAPI_WaitForSingleObject($hEventDataReady, 0) = $WAIT_TIMEOUT Then Return
  Local $tEvent = DllStructCreate("dword PID;char string[4092]", $pDebugInfo)
  _WinAPI_SetEvent($hEventBufferReady)
  Return SetExtended($tEvent.PID, $tEvent.string)
EndFunc   ;==>GetDebugOutput

Func Terminate()
  $bEnd = True
EndFunc   ;==>Terminate

 

Edited by Nine

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...