Manipulating the Keyboard Lights in Windows NT | CodeGuru

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 […]

Written By
CodeGuru Staff
CodeGuru Staff
Dec 18, 1999
1 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

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(“rnrnSample usage of IOCTL_KEYBOARD_SET_INDICATORS”);
    printf(“rnrn (the Scroll Lock light should be flashing)”);
    printf(“rnrnrnpress any key to exit…”);
    getch();
    printf(“rn”);
    SetEvent(heventCancel);
    WaitForSingleObject(hThread, 30000);
    CloseHandle(heventCancel);
    exit(0);
}

Downloads

Download demo project – 24 Kb

Download source – 6 Kb

CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.