キーボードフィルタドライバの使い方がわかってきました。いくらでも試して操作不能にできる仮想PC環境のおかげです。
例えば無変換キーを
ベースのkbfiltrはWDK 6001.18002です。スキャンコード一覧はこちらにあります。その他、ここやここやここを参考にしまし た。
レイアウトドライバで無変換にVK_KANAを割り当てれば、遜色ないカナキーにすることができるわけです。
ローレベルの制御をドライバで完了できれば、管理者権限のユーティリティが不要になります。一般権限では管理者権限アプリをフックできませんが、カナインジケータ程度の監視ならポーリングのような、より普通の実装にすべきなのでしょう。
VOID
KbFilter_ServiceCallback(
IN PDEVICE_OBJECT DeviceObject,
IN PKEYBOARD_INPUT_DATA InputDataStart,
IN PKEYBOARD_INPUT_DATA InputDataEnd,
IN OUT PULONG InputDataConsumed
)
{
PDEVICE_EXTENSION devExt;
KEYBOARD_INPUT_DATA kana[1] = {0};
PKEYBOARD_INPUT_DATA curInputData = InputDataStart;
ULONG tempConsumed = 0;
static int bInKana = 0;
devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
while( curInputData < InputDataEnd )
{
switch ( curInputData->MakeCode )
{
case 0x7b:
if ( ( InputDataStart->Flags & KEY_BREAK ) == 0 ) {
if ( bInKana == 0 ) {
bInKana = 1;
kana[0].MakeCode = 0x7b;
kana[0].Flags = KEY_MAKE;
tempConsumed = 0;
(*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)(
devExt->UpperConnectData.ClassDeviceObject,
&kana[0],
&kana[1],
&tempConsumed);
kana[0].Flags = KEY_BREAK;
tempConsumed = 0;
(*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)(
devExt->UpperConnectData.ClassDeviceObject,
&kana[0],
&kana[1],
&tempConsumed );
}
else {
curInputData++;
continue;
}
}
else {
bInKana = 0;
curInputData++;
continue;
}
break;
default:
tempConsumed = 0;
(*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)(
devExt->UpperConnectData.ClassDeviceObject,
curInputData,
curInputData + 1,
&tempConsumed );
}
curInputData++;
}
*InputDataConsumed = ( InputDataEnd - InputDataStart );
}
例えば無変換キーを
- KEYDOWNでKEYUPも発行
- KEYUPは無視
- リピート却下
ベースのkbfiltrはWDK 6001.18002です。スキャンコード一覧はこちらにあります。その他、ここやここやここを参考にしまし た。
レイアウトドライバで無変換にVK_KANAを割り当てれば、遜色ないカナキーにすることができるわけです。
ローレベルの制御をドライバで完了できれば、管理者権限のユーティリティが不要になります。一般権限では管理者権限アプリをフックできませんが、カナインジケータ程度の監視ならポーリングのような、より普通の実装にすべきなのでしょう。
VOID
KbFilter_ServiceCallback(
IN PDEVICE_OBJECT DeviceObject,
IN PKEYBOARD_INPUT_DATA InputDataStart,
IN PKEYBOARD_INPUT_DATA InputDataEnd,
IN OUT PULONG InputDataConsumed
)
{
PDEVICE_EXTENSION devExt;
KEYBOARD_INPUT_DATA kana[1] = {0};
PKEYBOARD_INPUT_DATA curInputData = InputDataStart;
ULONG tempConsumed = 0;
static int bInKana = 0;
devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
while( curInputData < InputDataEnd )
{
switch ( curInputData->MakeCode )
{
case 0x7b:
if ( ( InputDataStart->Flags & KEY_BREAK ) == 0 ) {
if ( bInKana == 0 ) {
bInKana = 1;
kana[0].MakeCode = 0x7b;
kana[0].Flags = KEY_MAKE;
tempConsumed = 0;
(*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)(
devExt->UpperConnectData.ClassDeviceObject,
&kana[0],
&kana[1],
&tempConsumed);
kana[0].Flags = KEY_BREAK;
tempConsumed = 0;
(*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)(
devExt->UpperConnectData.ClassDeviceObject,
&kana[0],
&kana[1],
&tempConsumed );
}
else {
curInputData++;
continue;
}
}
else {
bInKana = 0;
curInputData++;
continue;
}
break;
default:
tempConsumed = 0;
(*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)(
devExt->UpperConnectData.ClassDeviceObject,
curInputData,
curInputData + 1,
&tempConsumed );
}
curInputData++;
}
*InputDataConsumed = ( InputDataEnd - InputDataStart );
}
コメントする