Le développement de greffon (1.x)

Comment développer des greffons pour KeePass 1.x.

Cette documentation s'applique aux greffons de KeePass 1.x (toutes les versions ≥ 1.15). Les greffons 1.x sont fondamentalement différents des greffons 2.x. Les greffons 2.x ne peuvent pas être chargés par KeePass 1.x.

Une documentation détaillée du SDK est disponible ici : Plugin SDK Documentation.


Les exigences

Avant de pouvoir commencer à développer un greffon KeePass, vous avez besoin des prérequis suivants :

  • Le dernier package de code source de KeePass. Vous pouvez l'obtenir auprès du site Web de KeePass.
  • Un IDE/compilateur de développement C++.
  • Le SDK de la plate-forme Windows.

L'API du greffon KeePass utilise certains concepts de la norme du Component Object Model (COM). Si vous n'avez pas d'expérience avec COM, alors les pages suivantes sont recommandées pour la lecture :


Le tutoriel pas à pas

Démarrez votre IDE préféré et créez un nouveau projet Win32 (type d'application DLL, projet vide). Dans ce tutoriel, l'exemple de greffon que nous développons s'appelle TestPlugin. Créez deux fichiers dans le nouveau projet : un fichier source C++ (TestPlugin.cpp) et un fichier d'en-tête (TestPlugin.h).

Afin d'accéder aux interfaces KeePass, vous devez inclure un fichier d'en-tête du SDK KeePass : placez une instruction #include dans le fichier TestPlugin.h, qui inclut le fichier KeePassLibCpp/SDK/KpSDK.h du code source de KeePass.

Les DLL Windows peuvent éventuellement implémenter une fonction DllMain. Alors si vous en voulez une (non requis par KeePass cependant), alors en implémenter une par défaut maintenant dans le fichier TestPlugin.cpp (qui retourne toujours juste TRUE) :

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { UNREFERENCED_PARAMETER(hinstDLL); UNREFERENCED_PARAMETER(fdwReason); UNREFERENCED_PARAMETER(lpvReserved); return TRUE; }

L'étape suivante consiste à créer une classe de greffon, qui doit implémenter l'interface IKpPlugin. Alors, recherchez l'interface IKpPlugin (classe C++ abstraite) et concevez une classe qui implémente toutes ces méthodes. Vous trouverez des détails sur les méthodes ici Plugin SDK Documentation.

Exportez maintenant une fonction que KeePass utilisera pour créer une instance de votre classe de greffon :
KP_EXPORT HRESULT KP_API KP_I_CREATEINSTANCE_DECL(REFIID riid, void** ppvObject, IKpUnknown* pAPI);
Dans cette fonction, vous devrez créer une instance de votre classe de greffon et stocker un pointeur d'interface du type demandé par KeePass (riid) dans le paramètre ppvObject. Le paramètre pAPI est un pointeur d'interface vers l'API KeePass, que vous devez stocker pour une utilisation ultérieure au cas où vous seriez en mesure de retourner une interface de greffon valide.

KeePass est actuellement proposé uniquement en tant qu'application ANSI, et non Unicode. Par conséquent, allez dans Projet → Testez les propriétés du plugin et choisissez Multi Byte comme jeu de caractères.

Il est recommandé (mais pas nécessaire) d'établir un lien statique avec la bibliothèque d'exécution (et la MFC, si vous l'utilisez). Pour ce faire, rendez-vous sur Projet → Tester les propriétés du plugin → C/C++ → Génération de code et choisissez une bibliothèque d'exécution ne se terminant pas par '-DLL'.

La dernière étape avant de créer votre greffon consiste à ajouter une ressource d'information de version. Alors, allez dans l'onglet 'Ressources' du projet de greffon et ajoutez une ressource de type 'Version'. Ici, définissez le nom du produit sur KeePass Plugin. Tous les autres champs peuvent être librement définis sur des chaînes de votre choix.

Exemple. Vous pouvez trouver une version entièrement documentée et étendue de ce simple greffon sur la page web des plugins KeePass ("Test Plugin").


Les conventions et recommandations relatives aux greffons

Les conventions :

  • Le fichier DLL doit avoir une ressource d'informations de version, dans laquelle le nom du produit est défini sur KeePass Plugin. KeePass utilise ceci pour déterminer si la DLL est un greffon KeePass ou non (c'est-à-dire si vous ne créez pas une ressource d'informations de version avec cette chaîne, alors KeePass ne chargera pas votre fichier DLL).
  • Si vous souhaitez utiliser le nom "KeePass" en tant que partie du nom de votre plugin, alors préfixez/ajoutez directement un préfixe/suffixe non numérique. Par exemple : "KeePassSync" est correct, mais "KeePass Sync" ne l'est pas.
  • Un greffon KeePass doit exporter la fonction suivante :
    KP_EXPORT HRESULT KP_API KP_I_CREATEINSTANCE_DECL(REFIID riid, void** ppvObject, IKpUnknown* pAPI);

    KeePass appellera cette fonction pour créer une instance de votre classe de greffon. Vous devez retourner une interface de type riid dans le paramètre ppvObject, si votre classe de greffon prend en charge cette interface (il retournera S_OK). Sinon, positionnez ppvObject sur NULL et retournez E_NOINTERFACE. Vous pouvez stocker le pointeur d'interface pAPI pour une utilisation ultérieure. KeePass garantit que le pointeur est valide tant qu'il a un pointeur vers votre instance de classe de greffon.

    Important : vérifiez explicitement pour quelle interface KeePass demande (riid), sinon votre greffon ne sera pas descendant compatible et pourrait planter dans les futures versions de KeePass.
  • Un greffon KeePass peut éventuellement exporter les fonctions suivantes :
    KP_EXPORT HRESULT KP_API KP_I_INITIALIZELIB_DECL(IKpUnknown* pAPI);
    KP_EXPORT HRESULT KP_API KP_I_RELEASELIB_DECL(IKpUnknown* pAPI);

    KeePass appellera la première fonction après le chargement de la DLL, et la seconde un peu avant le déchargement de la DLL.

    Vous ne devez pas stocker le pointeur d'interface pAPI pour une utilisation ultérieure. Considérez les pointeurs comme temporaires ; ils pourraient devenir invalides dès que vous retournez depuis KP_I_INITIALIZELIB_DECL ou KP_I_RELEASELIB_DECL. Les valeurs du pointeur d'interface pAPI transmises à KP_I_INITIALIZELIB_DECL et KP_I_RELEASELIB_DECL ne sont pas garanties comme étant les mêmes comme chacune d'entre elles, ou comme la valeur de pointeur transmise à KP_I_CREATEINSTANCE_DECL.
  • Le protocole est DllMain (si présent), KP_I_INITIALIZELIB_DECL (si présent), KP_I_CREATEINSTANCE_DECL, méthodes d'interface de greffon, KP_I_RELEASELIB_DECL (si présent).
  • KeePass utilise le jeu de caractères multi-octets. Par conséquent, assurez-vous que vous compilez également votre greffon en mode jeu de caractères multi-octets, et pas Unicode.

Les recommandations :

  • Tous les fichiers de greffon doivent commencer par un préfixe commun. Par exemple : si votre greffon s'appelle VariousImport, alors le fichier DLL peut être nommé VariousImport.dll et son fichier d'aide VariousImport.html. Si vous n'utilisez pas de préfixe commun, alors les utilisateurs peuvent rencontrer des problèmes d'écrasement lors de l'installation de plusieurs greffons, car tous les greffons doivent être copiés dans le répertoire de l'application KeePass. Par exemple : s'il y a un greffon qui est livré avec un fichier ReadMe.txt et un autre greffon qui est également livré avec un tel fichier, alors ce dernier écrase le fichier readme du premier, ou l'utilisateur choisit de ne pas l'écraser et le fichier readme du deuxième greffon n'est alors pas disponible. En utilisant un préfixe commun cela évite ce problème.
  • Le bloc d'informations sur la version doit au moins être disponible en langue anglaise (États-Unis).
  • Il existe deux implémentations de l'interface IKpConfig. Une implémentation est identifiée par CLSID_KpConfig, l'autre par CLSID_KpConfig_ReadOnly. La première prend en charge à la fois la lecture et l'écriture, tandis que la seconde uniquement la lecture. Il est fortement recommandé que vous utilisiez la deuxième implémentation, si vous ne voulez lire que les éléments de la configuration.

    Essayer d'écrire en utilisant l'implémentation CLSID_KpConfig_ReadOnly vérifiera si KeePass est compilé en mode débogage et échouera en mode Release (et pourrait éventuellement détruire des parties de la configuration actuelle).


Mettre à jour les greffons depuis ≤ 1.14 à ≥ 1.15

Lors de la mise à jour d'un greffon depuis KeePass ≤ 1.14 à ≥ 1.15, il est fortement recommandé de créer un nouveau fichier de projet, de recommencer à zéro et copier/remplir les méthodes d'interface avec l'ancien code.

Remarques :

  • Il n'y a plus de fichier KeePass.lib. La nouvelle architecture des greffons est basée sur des interfaces. On inclut le fichier d'en-tête KpSDK.h c'est tout ce que vous avez à faire.

    Ne compilez avec aucun des fichiers du code source de KeePass ou n'incluez tout autre fichier d'en-tête que KpSDK.h.
  • Auparavant, un préfixe de ligne de commande était enregistré en définissant le membre de la structure d'informations du greffon cmdLineArgPrefix. Dans la nouvelle architecture, le préfixe de la ligne de commande doit être retourné par le membre de la méthode de l'interface du greffon GetProperty quand il est appelé par le paramètre KPPS_COMMANDLINEARGPREFIX.

    Votre GetProperty pourrait ressembler à ceci :

STDMETHODIMP_(LPCTSTR) CYourPluginImpl::GetProperty(LPCTSTR lpName) { if(lpName == NULL) retourne NULL ; if(_tcscmp(lpName, KPPS_COMMANDLINEARGPREFIX) == 0) return _T("mypluginprefix."); return NULL ; }

Le greffon ne doit pas accéder à la ligne de commande de KeePass après que tous les greffons ont été chargés. C'est parce qu'à ce moment KeePass ne peut bien sûr pas encore appeler la méthode GetProperty de votre greffon et par conséquent ne connaît pas encore le préfixe (et cela conduira à des avertissements 'option de ligne de commande inconnue'). Au lieu de cela, effectuez une ligne de commande dépendante de l'initialisation lorsque KeePass appelle votre gestionnaire de méthode OnMessage avec le code KPM_DELAYED_INIT.


La documentation détaillée de toutes les interfaces

Voir Plugin SDK Documentation.


Le Framework de greffon pour le C++

Merci à Bill Rubin, il existe un Plugin Framework disponible, facilitant le développement de greffons KeePass en C++. Les fonctionnalités en détail :

  1. Implémentation complète de l'interface IID_IKpUnknown.
  2. Implémentation de l'interface IID_IKpPlugin, excepté pour la fonction membre OnMessage, qui est toujours une application spécifique.
  3. La possibilité d'obtenir des pointeurs intelligents vers n'importe quelle autre interface KeePass, y compris IKpAPI, IKPCommandLine, IKpCommandLineOption, IKpConfig, IKpDatabase, IKpFullPathName et IKpUtilities.
  4. Implémentation de la fonction KpCreateInstance, dont le greffon doit s'exporter de ses DLL.
  5. Vérification complète des erreurs de l'établissement de liaison COM pour les éléments 3 et 4. Si une erreur est détectée, alors PFK affiche une boîte de message contenant toutes les informations sur l'erreur. Sans cette fonctionnalité, un greffon échouera dans la plupart des cas à se charger de façon silencieuse. Dans les autres cas, il échouera à remplir sa fonction.
  6. Utilitaires pratiques, pour afficher une boîte de message, traduire un code d'erreur Windows dans une chaîne en langage naturel et déclarez une chaîne standard indépendamment du type de caractère.
  7. Vérification du temps de la compilation des invocations de constructeur pour les pointeurs COM intelligents. Sans cette fonctionnalité, il est difficile pour un développeur d'interpréter les messages d'erreur du compilateur causés en utilisant le mauvais constructeur de pointeur COM intelligent.
  8. Le code PFK évite de définir des macros. Au lieu des modèles, les fonctions en ligne, typedefs et autres constructions C++ maintiennent des pratiques de conception sécurisée, sans pénalité d'exécution.

Il y a également un greffon de test disponible en utilisant le Framework de greffon.