A way to check key shift state in batch files

670 views
Skip to first unread message

tbone

unread,
Nov 10, 2010, 2:46:25 PM11/10/10
to
I'd like to be able to detect the state of the control, shift, and alt
keys within a batch file; i.e. which of these, if any, is currently
being pressed.

I used to have a little utility program for this, but I can't find it
now. I seem to recall it was one of those little debug-created
programs that called some interrupt or read a BIOS location to get the
state of the shift keys and returned that as an exit code which could
be tested with errorlevel.

Any pointers?

Thanks
tbone

foxidrive

unread,
Nov 10, 2010, 6:12:23 PM11/10/10
to

This will create KBFLAG.COM and there's a simple example.

KBFLAG -- by Nico Mark -- from PC Magazine, December 23, 1986

KBFLAG can be used to cause branching in batch files, so that execution of
different parts of the file can be dependent on the state of toggle and
shift
keys. You can, for example, abort execution of AUTOEXEC.BAT if the CapsLock
key has been toggled while CONFIG.SYS in running.

KBFLAG tests for a keystroke in the buffer, and sets errorlevel to the
value of
the key's KBFLAG in the ROM BIOS. Thus, if the Ins key has been toggled, it
will return an errorlevel of 128. Other values are:

1 = Right Shift
2 = Left Shift
4 = Ctrl key
8 = Alt key
16 = ScrollLock
32 = NumLock
64 = CapsLock
128 = Ins

(You can use sums of these values to correspond to combinations of keys, so
96 = CapsLock and NumLock together.)

If you put these lines at the start of autoexec.bat--

KBFLAG
IF ERRORLEVEL 64 GOTO :END

--and put the label :END at the end of the file, autoexec.bat will then
check
to see if CapsLock has been pressed, and will jump the end of the batch
if it
has. To prevent autoexec.bat from executing on bootup, simply hit CapsLock
while config.sys is running.

You can use variations of this technique to cause different sets of programs
to run during autoexec.bat (or any batch file). For example, Caps Lock
could
cause only a few programs to run; Alt + CapsLock could cause others; etc.


@echo off
Del /f /q /a t.dat >nul 2>&1
For %%b In (
"B840008ED8A01700B44CCD21"
) Do >>t.dat (Echo.For b=1 To len^(%%b^) Step 2
Echo WScript.StdOut.Write Chr^(Clng^("&H"^&Mid^(%%b,b,2^)^)^) : Next)
Cscript /b /e:vbs t.dat > "KBFLAG.COM"
Del t.dat >nul 2>&1

@echo off
:loop
kbflag
if %errorlevel% EQU 1 echo Right Shift
if %errorlevel% EQU 2 echo Left Shift
if %errorlevel% EQU 4 echo Ctrl key
if %errorlevel% EQU 8 echo Alt key
if %errorlevel% EQU 16 echo ScrollLock
if %errorlevel% EQU 32 echo NumLock
if %errorlevel% EQU 64 echo CapsLock
if %errorlevel% EQU 128 echo Ins
goto :loop
pause

--
Regards,
Mic

tbone

unread,
Nov 23, 2010, 10:03:15 PM11/23/10
to
On Thu, 11 Nov 2010 10:12:23 +1100, foxidrive
<foxi...@gotcha.woohoo.invalid> wrote:

>This will create KBFLAG.COM and there's a simple example.

Unfortunately, this is only part way there. It appears to handle keys
like Control as keystrokes, and not shift keys; i.e. keys that have a
state of either pressed or not pressed. Perhaps this is due to running
under Windows XP...

I expanded the sample batch file thus:

:loop
kbflags
set ec=%errorlevel%
set el=%ec%
set desc=

if %ec% == 0 set desc=None
if %ec% gtr 127 set desc=%desc%+Ins
if %ec% gtr 127 set /a ec=ec-128
if %ec% gtr 63 set desc=%desc%+CapsLock
if %ec% gtr 63 set /a ec=ec-64
if %ec% gtr 31 set desc=%desc%+NumLock
if %ec% gtr 31 set /a ec=ec-32
if %ec% gtr 15 set desc=%desc%+ScrollLock
if %ec% gtr 15 set /a ec=ec-16
if %ec% gtr 7 set desc=%desc%+Alt
if %ec% gtr 7 set /a ec=ec-8
if %ec% gtr 3 set desc=%desc%+Ctrl
if %ec% gtr 3 set /a ec=ec-4
if %ec% gtr 1 set desc=%desc%+LeftShift
if %ec% gtr 1 set /a ec=ec-2
if %ec% gtr 0 set desc=%desc%+RightShift
echo errorlevel %el%: %desc%
goto :loop

This shows me all the combinations that can be detected. Indeed, I see
lines like:

errorlevel 100: +CapsLock+NumLock+Ctrl
errorlevel 96: +CapsLock+NumLock
errorlevel 100: +CapsLock+NumLock+Ctrl
errorlevel 96: +CapsLock+NumLock

CapsLock and NumLock are being treated as expected - they have states
that are latched, if you will. But what you see above is not me
pressing the Ctrl key twice, it's me holding the control key down. So
every other loop sees the control key being "pressed" again,
presumably due to the keyboard repeat.

What I'd like is a way to take a peek at the instantaneous state of
any of the shift keys.

thx
tbone

Mark Joy

unread,
Dec 8, 2022, 7:23:43 AM12/8/22
to
On Wednesday, November 24, 2010 at 10:03:15 AM UTC+7, tbone wrote:
> On Thu, 11 Nov 2010 10:12:23 +1100, foxidrive
> <foxi...@gotcha.woohoo.invalid> wrote:
> >This will create KBFLAG.COM and there's a simple example.

When I run it under windows 8.1 64bit, it says "Unsupported 16-bit application". Can you provide a 32-bit or 64-bit app please?

Kerr-Mudd, John

unread,
Dec 8, 2022, 8:39:02 AM12/8/22
to
That's a step up from an asm query of the kb_flag byte at 0x0417

--
Bah, and indeed Humbug.

Kerr-Mudd, John

unread,
Dec 8, 2022, 9:03:07 AM12/8/22
to
Yup, the hex program provided by foxidrive in 2010
'B840008ED8A01700B44CCD21'
disassembled is

mov ax,0x40
mov ds,ax
mov al,[0x17]
mov ah,0x4C
int 0x21

far too big;


mine is 8 bytes:

pop ds
mov al,[0x0417]
mov ah,0x4C
int 0x21

JJ

unread,
Dec 8, 2022, 11:38:47 AM12/8/22
to
You can use this. The 32-bit EXE is only 1536 bytes. MASM assembly source
code included with the details about the program's exit code.

https://drive.google.com/file/d/1apCDoL_T4h5GlDhdSB2WXiLQwSpndWoZ/view

Kerr-Mudd, John

unread,
Dec 8, 2022, 2:52:34 PM12/8/22
to
I'm not up on this newfangled Windows stuff, but is the second 'insert'
offset (0a1h) correct?


lea esi, keyState
INVOKE GetKeyboardState, esi
xor eax, eax

;high byte: bios status flag 2
shl byte ptr [esi + 2dh], 1 ;insert down
rcl eax, 1
shl byte ptr [esi + 14h], 1 ;capslock down
rcl eax, 1
shl byte ptr [esi + 90h], 1 ;numlock down
rcl eax, 1
shl byte ptr [esi + 91h], 1 ;scrolllock down
rcl eax, 1
shr byte ptr [esi + 13h], 1 ;pause active
rcl eax, 1
shl byte ptr [esi + 2ch], 1 ;printscreen down
rcl eax, 1
shl byte ptr [esi + 0a4h], 1 ;left alt down
rcl eax, 1
shl byte ptr [esi + 0a2h], 1 ;left ctrl down
rcl eax, 1

;;###

;low byte: bios status flag 1
shr byte ptr [esi + 0a1h], 2 ;insert active

;; ## 02D?

rcl eax, 1
shr byte ptr [esi + 14h], 2 ;capslock active
rcl eax, 1
shr byte ptr [esi + 90h], 2 ;numlock active
rcl eax, 1
shr byte ptr [esi + 91h], 2 ;scrolllock active
rcl eax, 1
shl byte ptr [esi + 12h], 1 ;any alt down
rcl eax, 1
shl byte ptr [esi + 11h], 1 ;any ctrl down
rcl eax, 1
shl byte ptr [esi + 0a0h], 1 ;left shift down
rcl eax, 1
shl byte ptr [esi + 0a1h], 1 ;right shift down
rcl eax, 1

JJ

unread,
Dec 8, 2022, 7:56:14 PM12/8/22
to
On Thu, 8 Dec 2022 19:52:35 +0000, Kerr-Mudd, John wrote:
>
> I'm not up on this newfangled Windows stuff, but is the second 'insert'
> offset (0a1h) correct?
[snip]
> ;;###
>
> ;low byte: bios status flag 1
> shr byte ptr [esi + 0a1h], 2 ;insert active
>
> ;; ## 02D?
[snip]

Darn it! Thanks for the correction.
The files have been updated. Same URL.

Kerr-Mudd, John

unread,
Dec 9, 2022, 4:43:37 AM12/9/22
to
Cheers. Glad I was able to help in some small way.
For convenience I've added the url here:


https://drive.google.com/file/d/1apCDoL_T4h5GlDhdSB2WXiLQwSpndWoZ/view

Tom Del Rosso

unread,
Jan 2, 2023, 3:44:22 AMJan 2
to
Foxidrive passed away about 5 years ago.


--
Defund the Thought Police


Reply all
Reply to author
Forward
0 new messages