Bonjour à tous,
J’ai récemment décidé de passer au clavier bépo (toujours en phase d’apprentissage et d’exercices quotidien).
Avec un collègue on voulait juste générer les drivers nous-mêmes, rapidement et sans que ce soit trop complexe. On est parvenu à une méthode tout en un,
mais uniquement pour les bidouilleurs.
Du coup je propose une méthode « simple » de génération depuis MSKLC (Microsoft Keyboard Layout Creator) en faisant sauter la limitation du problème du tiret bas sur la barre d’espace.
Attention : cela fait sauter toutes limitations de la barre d’espace.
1) Téléchargez et installez MSKLC (dernière version en date : 1.4.6000.2)
2) Téléchargez le fichier bepo.klc
Une fois MSKLC installé, faites une copie du binaire principal (msklc.exe) et renommez le (par ex. en msklc2.exe).
Ouvrez la copie du programme (msklc2.exe) et faites une recherche dans un éditeur hexadécimal sur les octets suivants :
• 2D 05 04 2D 02 17 2A 17 0A
Remplacez le 0A par 2A, sauvegardez. Vous pouvez maintenant ouvrir le fichier bepo.klc et générer les drivers avec, directement !
Explication sur la manipulation
Comme indiqué sur le wiki ( bepo.fr/wiki/Pilote_Windows#MSKLC_et_pilote_b.C3.A9po ), lorsqu’on essaye de générer les drivers depuis le fichier bepo.klc avec MSKLC on obtient l’erreur suivante :
ERROR: 'VK_SPACE' in Shift State 'Ctl+Alt' must be made up of white space character(s), but is defined as '_' (U+005f) instead.
Msklc.exe est un programme .NET. On peut donc le décompiler avec des décompileurs spécialisés comme ILSpy (gratuit), dotpeek (gratuit) ou d’autres.
On trouve effectivement le message d’erreur dans les ressources du programme :
<data name="SpaceKeyNeedsWhiteSpaceCharacters" xml:space="preserve">
<value>'{0}' in Shift State '{1}' must be made up of white space character(s), but is defined as '{2}' ({3}) instead.</value>
</data>
On cherche où est référencée l’erreur dans le programme, on trouve une seul occurrence à « SpaceKeyNeedsWhiteSpaceCharacters » :
// Microsoft.Globalization.Tools.KeyboardLayoutCreator.Accept
private bool VerifySpaceBarIntegrity(ShiftState ss, bool fMustBeDefined)
{
if (ss.Characters == null || (ss.Characters.Length == 0 && !fMustBeDefined))
{
return true;
}
bool result = true;
if (ss.Characters.Length == 0)
{
this.WriteErrorToLogFile("SpaceKeyCharacterMustBeDefined", new string[]
{
"VK_" + Utilities.VkStringOfIvk((int)ss.VK),
this.m_stStateLabel[(int)ss.State]
});
result = false;
}
else if (!Utilities.IsSpacing(ss.Characters))
{
this.WriteErrorToLogFile("SpaceKeyNeedsWhiteSpaceCharacters", new string[]
{
"VK_" + Utilities.VkStringOfIvk((int)ss.VK),
this.m_stStateLabel[(int)ss.State],
ss.Characters,
Utilities.FromCharacterToUPlusForm(ss.Characters)
});
result = false;
}
return result;
}
Notez que la fonction coupable du message d'erreur se nomme "VerifySpaceBarIntegrity" 🙂
Avec ildasm (disponible avec Visual Studio), on peut désassembler le programme au niveau IL (Intermediate Language) :
.method private hidebysig instance bool
VerifySpaceBarIntegrity(class Microsoft.Globalization.Tools.KeyboardLayoutCreator.ShiftState ss,
bool fMustBeDefined) cil managed
// SIG: 20 02 02 12 80 90 02
{
// Method begins at RVA 0x41cc
// Code size 203 (0xcb)
.maxstack 6
.locals init (bool V_0,
string[] V_1,
string[] V_2)
IL_0000: /* 03 | */ ldarg.1
IL_0001: /* 6F | (06)0001CF */ callvirt instance string Microsoft.Globalization.Tools.KeyboardLayoutCreator.ShiftState::get_Characters()
IL_0006: /* 2C | 10 */ brfalse.s IL_0018
IL_0008: /* 03 | */ ldarg.1
IL_0009: /* 6F | (06)0001CF */ callvirt instance string Microsoft.Globalization.Tools.KeyboardLayoutCreator.ShiftState::get_Characters()
IL_000e: /* 6F | (0A)000025 */ callvirt instance int32 [mscorlib]System.String::get_Length()
IL_0013: /* 2D | 05 */ brtrue.s IL_001a
IL_0015: /* 04 | */ ldarg.2
IL_0016: /* 2D | 02 */ brtrue.s IL_001a
IL_0018: /* 17 | */ ldc.i4.1
IL_0019: /* 2A | */ ret
IL_001a: /* 17 | */ ldc.i4.1
IL_001b: /* 0A | */ stloc.0
…
Sur la colonne de gauche vous pouvez voir les octets qui constituent le code (et donc les octets recherchés donnés au début de ce message).
Concrètement, remplacer le ‘0x0A’ par ‘0x2A’ remplace une instruction par un ‘return’ direct : le reste du corps de la fonction n’est pas exécuté et donc la vérification sur la barre d’espace aussi. C’est assez « bourrin » et il existe d’autre manières de patcher le code, mais ça fonctionne…
Du coup la fonction ressemble à ça après la modification :
// Microsoft.Globalization.Tools.KeyboardLayoutCreator.Accept
private bool VerifySpaceBarIntegrity(ShiftState ss, bool fMustBeDefined)
{
return (ss.Characters != null && (ss.Characters.Length != 0 || fMustBeDefined)) || true;
}
La fonction renvoie tout le temps ‘True’ pour le cas qui nous intéresse (il n'y a donc plus aucune vérification sur la barre d'espace, ça peut être problématique dans certains cas j'imagine).
Voilà, je ne sais pas si c'est très utile, mais si jamais ça peut servir à quelqu'un...