Manipulating the Keyboard Lights in Windows NT

Environment: VC5, NT4 SP3-SP5

This code demonstrates manipulation of the keyboard indicator lights in Windows NT 4.0. A few relevant values were borrowed from the DDK headers, so it is not necessary to have the DDK installed, to build these sources.

There's really nothing fancy about this code, it creates a DOS device for the keyboard device, opens a handle to that device, and calls DeviceIoControl to send IOCTL function codes to the device.

It did require a fair amount digging around in the DDK to create this effect, and it is an interesting twist on an alternate UI mechanism, and thus I felt it might be suitable for inclusion in this archive.

A high-level, multi-threaded function to flash a keyboard light continuously in its own thread, is included. This call is demonstrated in the sample project.

NTKbdLites can be easily built for inclusion in a static link library by defining STATIC_LIBRARY on the compiler command line or in settings.


/***********************************************************
** NTKbdLites.c                                           **
**                                                        **
**  Copyright 1999 Mark J. McGinty, All Rights Reserved   **
**   Free Usage granted to the public domain.             **
**                                                        **
***********************************************************/

#include <windows.h>
#include <winioctl.h>
#include "NTKbdLites.h"

// Code can be built as either a DLL or a static link library
//
#ifdef STATIC_LIBRARY
#define DECLSPEC 
#else
#define DECLSPEC __declspec(dllexport)
#endif

// FlashKeyboardLight
//
// Flashes the keyboard indicator, specified by LightFlag, one time, 
// at the rate indicated by Duration. All lights are left in their
// previous states when this call returns.
//
// Possible LightFlags:
//      KEYBOARD_CAPS_LOCK_ON   
//      KEYBOARD_NUM_LOCK_ON    
//      KEYBOARD_SCROLL_LOCK_ON

int DECLSPEC FlashKeyboardLight(HANDLE hKbdDev, UINT LedFlag, int Duration)
{
    KEYBOARD_INDICATOR_PARAMETERS InputBuffer;    // Input buffer for DeviceIoControl
    KEYBOARD_INDICATOR_PARAMETERS OutputBuffer;   // Output buffer for DeviceIoControl
    UINT                LedFlagsMask;
    BOOL                Toggle;
    ULONG               DataLength = sizeof(KEYBOARD_INDICATOR_PARAMETERS);
    ULONG               ReturnedLength; // Number of bytes returned in output buffer
    int             i;

    InputBuffer.UnitId = 0;
    OutputBuffer.UnitId = 0;

    // Preserve current indicators' state
    //
    if (!DeviceIoControl(hKbdDev, IOCTL_KEYBOARD_QUERY_INDICATORS,
                &InputBuffer, DataLength,
                &OutputBuffer, DataLength,
                &ReturnedLength, NULL))
        return GetLastError();

    // Mask bit for light to be manipulated
    //
    LedFlagsMask = (OutputBuffer.LedFlags & (~LedFlag));

    // Set toggle variable to reflect current state.
    //
    Toggle = (OutputBuffer.LedFlags & LedFlag);

    for (i = 0; i < 2; i++)
    {
        Toggle ^= 1;
        InputBuffer.LedFlags = (LedFlagsMask | (LedFlag * Toggle));

        if (!DeviceIoControl(hKbdDev, IOCTL_KEYBOARD_SET_INDICATORS,
                    &InputBuffer, DataLength,
                    NULL,   0,  &ReturnedLength, NULL))
            return GetLastError();

        Sleep(Duration);
    }
    return 0;
}

HANDLE DECLSPEC OpenKeyboardDevice(int *ErrorNumber)
{
    HANDLE  hndKbdDev;
    int     *LocalErrorNumber;
    int     Dummy;

    if (ErrorNumber == NULL)
        LocalErrorNumber = &Dummy
    else
        LocalErrorNumber = ErrorNumber;

    *LocalErrorNumber = 0;
    
    if (!DefineDosDevice (DDD_RAW_TARGET_PATH, "Kbd",
                "\\Device\\KeyboardClass0"))
    {
        *LocalErrorNumber = GetLastError();
        return INVALID_HANDLE_VALUE;
    }

    hndKbdDev = CreateFile("\\\\.\\Kbd", GENERIC_WRITE, 0,
                NULL,   OPEN_EXISTING,  0,  NULL);
    
    if (hndKbdDev == INVALID_HANDLE_VALUE)
        *LocalErrorNumber = GetLastError();

    return hndKbdDev;
}

int DECLSPEC CloseKeyboardDevice(HANDLE hndKbdDev)
{
    int e = 0;

    if (!DefineDosDevice (DDD_REMOVE_DEFINITION, "Kbd", NULL))
        e = GetLastError();

    if (!CloseHandle(hndKbdDev))                    
        e = GetLastError();

    return e;
}

// Thread procedure to make a light flash continuously.
//
DWORD WINAPI FlashKeyboardLightThd(LPVOID lpv)
{
    LPFLASH_KBD_THD_INIT pInit = (LPFLASH_KBD_THD_INIT)lpv;
    FLASH_KBD_THD_INIT Init = *pInit;
    HANDLE  hndKbdDev;
    HANDLE  heventCancel = OpenEvent(EVENT_ALL_ACCESS, FALSE, Init.EventName);

    if (heventCancel == NULL)
        ExitThread(-1);

    hndKbdDev = OpenKeyboardDevice(NULL);
    if (hndKbdDev == INVALID_HANDLE_VALUE)
    {
        CloseHandle(heventCancel);
        ExitThread(-1);
    }

    for (;;)
    {
        FlashKeyboardLight(hndKbdDev, Init.LightFlag, Init.Duration);
        
        if (WaitForSingleObject(heventCancel, Init.Duration) != WAIT_TIMEOUT)
            break;
    }

    Sleep(Init.Duration);

    CloseHandle(heventCancel);
    CloseKeyboardDevice(hndKbdDev);
    
    ExitThread(0);
    return 0;
}

// Builds structure and creates thread, to flash light continuously
//
HANDLE DECLSPEC FlashKeyboardLightInThread(UINT LightFlag, int Duration, LPSTR EventName)
{
    DWORD ThreadId;
    static FLASH_KBD_THD_INIT FlashInit;

    FlashInit.LightFlag = LightFlag;
    FlashInit.Duration = Duration;
    lstrcpyn(FlashInit.EventName, EventName, 128);

    return CreateThread(NULL, 0, FlashKeyboardLightThd, (LPVOID)&FlashInit, 0, &ThreadId);
 
}

/***********************************************************
** NTKbdLites.h                                           **
**                                                        **
**  Copyright 1999 Mark J. McGinty, All Rights Reserved   **
**   Free Usage granted to the public domain.             **
**                                                        **
***********************************************************/

#include <windows.h>

//
// Define the keyboard indicators.
//

#define IOCTL_KEYBOARD_SET_INDICATORS        CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0002, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_KEYBOARD_QUERY_TYPEMATIC       CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0008, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_KEYBOARD_QUERY_INDICATORS      CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0010, METHOD_BUFFERED, FILE_ANY_ACCESS)


typedef struct _KEYBOARD_INDICATOR_PARAMETERS {
    USHORT UnitId;          // Unit identifier.
    USHORT    LedFlags;     // LED indicator state.

} KEYBOARD_INDICATOR_PARAMETERS, *PKEYBOARD_INDICATOR_PARAMETERS;

#define KEYBOARD_CAPS_LOCK_ON     4
#define KEYBOARD_NUM_LOCK_ON      2
#define KEYBOARD_SCROLL_LOCK_ON   1

#ifdef STATIC_LIBRARY
#define DECLSPEC 
#else
#define DECLSPEC __declspec(dllexport)
#endif

int DECLSPEC FlashKeyboardLight(HANDLE hKbdDev, UINT LightFlag, int Duration);
HANDLE DECLSPEC OpenKeyboardDevice(int *ErrorNumber);
int DECLSPEC CloseKeyboardDevice(HANDLE hndKbdDev);
HANDLE DECLSPEC FlashKeyboardLightInThread(UINT, int, LPSTR);

typedef struct {
    UINT        LightFlag;
    int     Duration;
    char        EventName[128];
} FLASH_KBD_THD_INIT, *LPFLASH_KBD_THD_INIT;

/*********************************************************** ** NTFlashScrollLight.c ** ** ** ** Copyright 1999 Mark J. McGinty, All Rights Reserved ** ** Free Usage granted to the public domain. ** ** ** ** ** ** A short test program, to excersize NTKbdLites.c ** ** ** ***********************************************************/ #include <windows.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <conio.h> #include "NTKbdLites.h" #define CANCEL_EVENT_NAME "TestThreadedFlasherEvent" void __cdecl main(int argc, char **argv) { HANDLE heventCancel = CreateEvent(NULL, FALSE, FALSE, CANCEL_EVENT_NAME); HANDLE hThread = FlashKeyboardLightInThread(KEYBOARD_SCROLL_LOCK_ON, 250, CANCEL_EVENT_NAME); printf("\r\n\r\nSample usage of IOCTL_KEYBOARD_SET_INDICATORS"); printf("\r\n\r\n (the Scroll Lock light should be flashing)"); printf("\r\n\r\n\r\npress any key to exit..."); getch(); printf("\r\n"); SetEvent(heventCancel); WaitForSingleObject(hThread, 30000); CloseHandle(heventCancel); exit(0); }

Downloads

Download demo project - 24 Kb
Download source - 6 Kb

About the Author

Mark McGinty

Programming professionally for 15 years I've used a wide range of languages, including C/C++, x86 assembler, JScript, numerous forms of VB, SmallTalk and T-SQL, to name a few. Much of what I do these days involves databases to some degree, mostly back-end database/application architecture for data-driven websites.

IT Offers

Comments

  • Jordan shoes mentioned Gene to pay off the manufacturer, a margin of Nike

    Posted by TaddyGaffic on 04/22/2013 07:22pm

    The sole of shoes are made from high quality rubber material and come with the lining. One can easily search for Vans footwear in the various online stores where they are easily available at great discount prices. These come in almost an infinite amount of [url=http://markwarren.org.uk/goodbuy.cfm]nike free[/url] color and are usually on the cheap side. Experts as well as the rights of employees in regards to the apple can annihilate the Nike Air Max For travel arrangements in developing abjection can be a acceptable accord added in comparison to they're prevention, nonetheless they do accommodate sports sports athletes while using high duke inside their profession. Bargain Nike Air Max 2009 aswell provides countless jobs inside the nations absolutely area it's hardly accessible to acquire a job. In Indonesia, for archetype nike air max 90, even acknowledging baby assets [url=http://markwarren.org.uk/property-waet.cfm]air max 90 uk[/url] in barter for plan Air Max, however, Nike bargain shoes inside a aught bulk adaptation and utilisation of the circadian needs.. Nike Zoom Vapor VI Tour Men`s tennis shoe is a great shoe popular in the tennis courts. It has Fly wire upper for ultra support and light weight ability, it sits on a frame that gives extra heel support and contains a full-length durable rubber support and herring bone pattern. It also has extra traction for all surfaces of play.. Write a Shakespeare Sonnet without any effort! Express loving [url=http://turbo-vac.co.uk/components_13.cfm]nike free 4.0 v2[/url] feelings in a sonnet in Shakespeare's own words in 15 minutes. The rhyme scheme of a Sonnet is a,b,a,b,c,d,c,d,e,f,e,f,g,g. Think of a theme like "love" "death" or "deceit", then choose your lines in the rhyme pattern and put a Sonnet together using the programme

    Reply
  • ALebA Xkg laoT

    Posted by lGLEpQDMdU on 03/11/2013 08:41pm

    lorazepam mg how to buy ativan no prescription - can overdose ativan

    Reply
  • prandupseda Eldemedge Pourrysox 13

    Posted by CesSmeattypete on 12/28/2012 04:46am

    full of generous suggestion to enterprise and labor. God has placed upon At a hath power to kill http://xn--the-ti4b3ah5gqi5isdc.com オンラインカジノ ボーナスへの無料ガイド but it wasn't to be thought of. Otherwise he seemed fairly well and do her good," he said to himself, as a stony hill sloped オンラインカジノ

    Reply
  • payday advance online lenders

    Posted by Kina64 on 12/10/2012 08:24pm

    imf short term lending facility [url=http://shorttermfinancevi.tumblr.com]short term finance brisbane[/url] unsecured loans retired people

    Reply
  • instant cash advance sydney

    Posted by Odell08 on 12/10/2012 06:05am

    cash loans in dallas texas [url=http://noteletrackpaydayloans12.tumblr.com]http://noteletrackpaydayloans12.tumblr.com[/url] payday loan new zealand

    Reply
  • paycheck advance omaha ne

    Posted by Sun69 on 12/10/2012 12:32am

    high risk payday loan lenders [url=http://approvedcashadvance.tumblr.com]approved cash advance[/url] paycheck loans lake charles la

    Reply
  • cash loans las vegas nv

    Posted by Ross71 on 12/09/2012 09:54pm

    cash now advance clinton hwy [url=http://shorttermfinancevi.tumblr.com]short term finance[/url] cash loan with no faxing

    Reply
  • advance cash maryland

    Posted by Edward36 on 12/09/2012 07:08pm

    requirements to get a payday loan [url=http://quickloansuk.tumblr.com]quick loans uk[/url] quick loan taylorsville

    Reply
  • small payday loans for bad credit

    Posted by Eura19 on 12/09/2012 05:50pm

    bad credit personal loans no credit check [url=http://easycashloanstoday.tumblr.com]click over here[/url] cash advance loan lenders

    Reply
  • emergency cash loan lenders

    Posted by Sharlene03 on 12/09/2012 02:47pm

    cash advance loans australia [url=http://usapaydayloanss.tumblr.com]usa payday loans burlington[/url] online renewal of advance parole

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Go Deeper

  • This online eBook provides insight and advice on how to build an effective disaster recovery strategy in the evolving world of virtual …
  • When the economy is stable, a company's IT organization may view Finance as just one of many internal customers competing for attention. But …
  • Increasing demands placed on IT, along with tightening budgets has prompted IT leaders to seek out alternative technologies and improved …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds