4
votes

I need to swap Alt keys functionality in Windows 7. A big company needs that for old people that were writing on typewriters, which had diacritic characters key on the left side, but Win7 which they are working on now has right Alt for this purpose.

Two days of research brought me to a driver solution. I need source code for original Windows 7 drivers (two .sys files seem to be the keyboard drivers), and possibily to modify them in Windows DDK. Or I need to make an additional driver that would work with the default ones. As I can see, the solution would be in C or C++. But what way do I have to go to accomplish this? What steps should I take?

The limits are:

  1. One system restart only for driver installation.
  2. A simple way to swap Alt keys while working in Win7 (swap Alt keys by pressing them both).
  3. No Win7 keyboard remapping which needs a restart.

Added later: I have everything I need, but not the code that will handle the swapping. For example, I've made a switch for right Shift and Enter, because there is only one scancode sent. But left Alt sends one and right Alt sends two scancodes:

VOID
KbFilter_ServiceCallback(
IN PDEVICE_OBJECT  DeviceObject,
IN PKEYBOARD_INPUT_DATA InputDataStart,
IN PKEYBOARD_INPUT_DATA InputDataEnd,
IN OUT PULONG InputDataConsumed
)
/*++

Routine Description:

Called when there are keyboard packets to report to the Win32 subsystem.
You can do anything you like to the packets.  For instance:

o Drop a packet altogether
o Mutate the contents of a packet
o Insert packets into the stream

Arguments:

DeviceObject - Context passed during the connect IOCTL

InputDataStart - First packet to be reported

InputDataEnd - One past the last packet to be reported.  Total number of
               packets is equal to InputDataEnd - InputDataStart

InputDataConsumed - Set to the total number of packets consumed by the RIT
                    (via the function pointer we replaced in the connect
                    IOCTL)

Return Value:

Status is returned.

--*/
{
PDEVICE_EXTENSION   devExt;
WDFDEVICE   hDevice;

hDevice = WdfWdmDeviceGetWdfDeviceHandle(DeviceObject);

devExt = FilterGetData(hDevice);

if (InputDataStart->MakeCode==0x1c)
    InputDataStart->MakeCode=0x36;
else if (InputDataStart->MakeCode==0x36)
    InputDataStart->MakeCode=0x1c;
else if (InputDataStart->MakeCode==0x9c)
    InputDataStart->MakeCode=0xb6;
else if (InputDataStart->MakeCode==0xb6)
    InputDataStart->MakeCode=0x9c;

(*(PSERVICE_CALLBACK_ROUTINE)(ULONG_PTR) devExt->UpperConnectData.ClassService)(
    devExt->UpperConnectData.ClassDeviceObject,
    InputDataStart,
    InputDataEnd,
    InputDataConsumed);
}

So I simply swap the scancodes of pressing and releasing both keys individually. Right Alt is sending two scancodes and I'm not sure if it does that by two calls of this function or makes two scancodes in the InputDataStart structure. I'll try to beep every Alt scancode but your help would be appreciated.

1
You probably want to write a class filter driver (sitting between the low-level device driver and kbdclass) rather than trying to modify existing drivers. The DDK contains a sample keyboard filter driver and also the source code for kbdclass, which may be useful as a reference.Harry Johnston
I'll try that and give a feedback.pbies
I've built kbfilter (sample keyboard filter driver) to .sys, installed it (in Device Manager as instructions says) and restarted Windows - keyboard stopped working, it just didn't responded for key presses. I've needed to uninstall this driver to make the keyboard work again (by on-screen keyboard). Seems, that the original kbfilter in the DDK (exactly WDK 7.1.0) which claims to be working fine without changes - is not working. I've made whole the process as in kbfiltr.htm file. I wasn't using Visual Studio or anything else beside build.exe and one file needed to install the driver. Any help?pbies
Needed to start Win7 with no driver signing requirement.pbies
Did you consider using a keyboard re-mapper (registry fix) like SharpKeys? sharpkeys.codeplex.comSergey L.

1 Answers

1
votes

Solution:

if (InputDataStart->MakeCode==0x38 || InputDataStart->MakeCode==0xb8)
    InputDataStart->Flags^=KEY_E0;

which swaps right-left Alt keys functionality.

Now I need to make the swapping configurable. For the best - by pressing both Alts.