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.

Comments

  • escada perfume macys

    Posted by sliplysag on 07/14/2013 07:43am

    Looking good does more than create impressions on others at work or socially, it shows that we value ourselves when we make the best of our looks. The next step is to do price comparisons and see who offers high quality products at prices you find suitable.. Perhaps it is time to expand your wardrobe and not wear the same item of clothing over and over again. They may indeed be tripping, and may be the one who requires a makeover. Clothing and accessories do not have to be expensive. If you are not properly dressed your employers may prefer selecting someone else who has spent more time on their attire and personal appearance. You can either be offended or consider if the comment has credibility. No matter what age we are, we could all use a change in clothing and style from time to time. As we grow up and get into our busy working lives, the fun should not stop, nor should your dedication to looking good. Having the right clothing and accessories for all occasions makes life easier. After all, we deserve to take pride in our appearance and improve the environment for others too. Believe it or not, we self-project a great deal through the way we dress, often subconsciously. It is possible to appear impeccably attired in simple affordable clothing. Remember being young, fun and carefree? In our younger days the focus centres more on having fun for the weekend rather than on dress. Then there are those who do not take care and manage to look sloppily attired in the most expensive clothing. Outrageous you may say? While it is not commonly openly admitted, it is a fact that personal grooming, clothing and our style of dress communicate a great deal about who we are. Buying clothing and accessories that complement your looks is significant to your own brand of marketing either in personal or business relationships. It follows then that making an effort to find, high quality, durable clothing and accessories pays off. It could be a relevant factor as to whether you get a work opportunity, promotion or a raise. Being able to shop from the comfort of your own home in your comfortably styled pyjamas beats an hours drive, finding parking, and wading through busy stores. Everyone has their own sense of style, and it is important to respect each others different looks and beliefs. So next time a friend gives you advice think it over. Whatever effort you expend on the task of acquiring clothing and accessories to suit your personal style, it will not be wasted. As we go through life our sense of style changes according to our personal identity. So your best friend comes over and remarks that you could use some more style. It is crucial to wear clothes that suit you and fit well and others may have a better eye than you for this. You can start your research by looking at websites online that offer clothing that appeals to you. Shopping online is a useful way to find great deals on high quality clothing and accessories and can save you a lot of time. Knowing where to find the best products, and the ones that fit your personal sense of style can take some time and effort. Taking feedback from others whom you know to have good taste is very helpful. Looking professional in the business world is essential. One does not have to "dress to the nines" to look great.Personal grooming and the way we dress makes an important first impression. Style and looking good does not have a price tag to it. [url=http://www.lovelythings.me.uk/rihanna-perfume/]rihanna perfume ad[/url] Or they could be on point

    Reply
  • Hvordan du skal bruke ghd rettetang

    Posted by carpinteyrobgq on 06/14/2013 01:43pm

    [url=http://ghdrettetangtilbud.qsite.dk/]ghd rettetang[/url] På grunn av masse popularitet og pris av GHD rettetang, har de blitt en lukrativ mulighet for produsenter av piratkopierte varer, sammen med designer solbriller, Ugg støvler og sportswear.The suksess for enhver bedrift fører uunngåelig til produksjon av billig knock-offs og GHD rettetang er ingen exception.The selskaper som setter opp falske GHD nettsteder er vanligvis basert på langt øst som også er der de produserer sine produkter. de deretter kjøper. com and.co.uk nettstedet navn å se mer legitimt. Du bør være forsiktig, bare fordi en nettside ender i. co.uk, betyr det ikke at produktene kommer fra Storbritannia. Personen som driver nettstedet kan være hvor som helst i verden. [url=http://www.rettetangnewsnorge.com/]ghd rettetang pris[/url] Mange lurer på hvilken type rettetang som er aller best og holder lenge, for meg er det kun ett riktig svar på dette. Nemlig GHD! Den varmes opp på under 30 sekunder, glir lett gjennom håret og er enkel å bruke uansett om man har erfaring med rettetenger fra før av, eller om man aldri har vært borti en.Med tengene følger det med en 2 års garanti som er veldig omfattende. Ghd tengene finnes i 3 størrelser .Julen sendte GHD til kjæresten din! [url=http://www.rettetangnorgenews.net/]ghd rettetang[/url] Du kan også lufttørke håret. Dette tar selvsagt mye lenger tid, men det er mye bedre for håret. I mens håret tørker naturlig kan du gre igjennom det gjevnlig, da blir håret mye rettere enn om du bare skulle latt det tørke vanlig!Alt du trenger å gjøre for å krølle meg håret med en GHD hår rettetang er dele det ved hjelp av klipp- og bånd og begynne fra det nederste laget av håret på den ene siden av hodet. Ved hjelp av en av disse GHD skjønnhetsprodukter som er om lag en tommers bredt bør nok.

    Reply
  • Dit GHD hjemmeside tillader dig at sorten dit serienummer

    Posted by motherdhmm on 05/30/2013 11:46am

    [url=http://www.blog.cheapbeatsbydre.co.nz/beats-by-dre-headphones]beats by dre headphones[/url] Nu enden af elementet er normalt fluorescerende, og jeg har brug for glat hår. Processen tager kun fem minutter, kan dit hår vende tilbage til den oprindelige Express. Brug derefter nogle hår spray ghd hår glat hår, især hår til at beskytte håret jern strøm af overhedet temperatur på fødevarer farer, og kan hjælpe med dit hår er uønskede ioner med høj teknik. Det er delikat og ren. GHD Danmark emballage er ofte særligt, plus de er nemme at håndtere. [url=http://www.blog.cheapbeatsbydre.co.nz/]beats by dre[/url] lukket auto design: den nye generation af glattejern salg du ved et uheld glemmer lukket efter 15 minutters glat hår vil udstede et “bip” til “være seje” status, der i ren nedkøling inden for 15 minutter ville have været en sådan lukket indtil lyden at minde sig selv. Bemærk: Hvis den lige håret i “at være cool” status efter det program, du har brug for at følge, kan være direkte relateret til tab, så timeren konfiguration fra bunden. [url=http://www.buy-beatsdrdre.com/category/new-beats-dr-dre-headphones]Beats By Dr Dre[/url] Den faktiske given mængde inde i mængden middage indeholder 4. 5 inches lang med henblik på dels. 5 ins tykkelse og også du kan vælge afhængig af god låse rækkevidde, beregnet til alle, der er en specialist og endnu nybegynder og meget mere. i situation, du har fået korte Lokker, kan din specifikke to, fem inches massiv skål være nok. En stor del langt mere sammen med større manke, kan det især øget væsentlig en aftenmåltid kan anbefales

    Reply
  • Wonderful Site You Have Here!

    Posted by FronginiovaJA on 05/21/2013 12:38am

    I used to read a great deal of books but now I surf the internet looking for really good blogs like this one to read. this was a good read thanks!

    Reply
  • 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
  • Loading, Please Wait ...

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

Top White Papers and Webcasts

  • Do you know where your data is? Consumer cloud-based file sharing services store your sensitive company data on servers outside of your control, outside of your policy and regulatory guidelines – maybe even outside your country – and not managed by you. The potential for data leakage, security breaches, and harm to your business is enormous. Download this white paper to learn about file sync and share alternatives that allow you to manage and protect your sensitive data while integrating and …

  • Live Event Date: August 20, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT When you look at natural user interfaces as a developer, it isn't just fun and games. There are some very serious, real-world usage models of how things can help make the world a better place – things like Intel® RealSense™ technology. Check out this upcoming eSeminar and join the panel of experts, both from inside and outside of Intel, as they discuss how natural user interfaces will likely be getting adopted in a wide variety …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds