Partage

Fonction pour monter les droits de IRQL à DISPATCH

20 juin 2018 à 16:06:00

Hello world

Je travaille tjr sur un vieux projet qui nécessite d'utiliser VSC++ 2003. à un moment intervient ce bout de code que je ne comprend absolument pas, pourriez vous m'eclairer:

KIRQL(*KeRaiseIrqlToDpcLevelFix)(void) = &KeRaiseIrqlToDpcLevel;


Declaration et definitions:

// IRQL
typedef UCHAR KIRQL, *PKIRQL;
#define PASSIVE_LEVEL 0             // Passive release level
#define LOW_LEVEL 0                 // Lowest interrupt level
#define APC_LEVEL 1                 // APC interrupt level
#define DISPATCH_LEVEL 2            // Dispatcher level

// KeRaiseIrql:
// Raises IRQL to some value.
//
// Differences from NT: None.
#define KeRaiseIrql KfRaiseIrql
NTSYSAPI
EXPORTNUM(190)
VOID
__fastcall
KfRaiseIrql(
    IN KIRQL NewIrql,
    OUT PKIRQL OldIrql
    );

// KeRaiseIrqlToDpcLevel:
// Raises IRQL to DISPATCH_LEVEL.  Like KeRaiseIrql except returns old level directly.
//
// Differences from NT: None.
NTSYSAPI
EXPORTNUM(129)
KIRQL
NTAPI
KeRaiseIrqlToDpcLevel(
    VOID
    );

// KeLowerIrql:
// Lowers IRQL.
#define KeLowerIrql KfLowerIrql
NTSYSAPI
EXPORTNUM(161)
VOID
__fastcall
KfLowerIrql(
    IN KIRQL NewIrql
    );



De plus a la compilation j'ai cette erreur:

error C2440: 'initializing' : cannot convert from 'KIRQL (__stdcall *)(void)' to 'KIRQL (__cdecl *)(void)' This conversion requires a reinterpret_cast, a C-style cast or function-style cast

pourriez vous m'aider svp?

Merci

-
Edité par nonosto 22 juin 2018 à 5:52:32

20 juin 2018 à 16:59:25

Dans le premier code, tu as 2 declarations de pointeurs de fonction (avec un code imbittable, comme toujours avec les pointeurs de fonctions) puis la declaration d'une variable "l".

Pour l'erreur, c'est explicite il me semble. Les pointeurs de fonction ne sont pas identique, il faut donc utiliser "a reinterpret_cast, a C-style cast or function-style cast".

Pour poser des questions ou simplement discuter informatique, vous pouvez rejoindre le discord NaN.
20 juin 2018 à 19:29:33

Merci bcp. As tu des piste pour re ecrire ceci plus simplement stp
20 juin 2018 à 19:35:23

Avec MSVC 2003 ? Pas trop. Utilises des typedef pour simplifier le code. Mais c'est plus du code C que du C++, du coup ca restera moche. Difficile de clean ca.
Pour poser des questions ou simplement discuter informatique, vous pouvez rejoindre le discord NaN.
20 juin 2018 à 19:41:30

Pour la "défense" de @nonosto, il s'agit de code pour Driver/Kernel Windows, qui est une API C, et de très très bas niveau (matériel).

IRQL, c'est pour niveau d’interruption HARDWARE que doit avoir au minimum l'interruption pour que le CPU la prenne en compte.

Donc, non, le projet n'est pas "tanqué" dans "VSC++ 2003", mais utilise très vraisemblablement NMAKE en sous-main pour générer le bidule depuis du code C, pas C++.

Vous êtes au niveau du Kernel et vos fonctions de callback doivent se conformer rigoureusement aux conventions d'appel, spécifiées par tous les machins "NTSYSAPI", "NTAPI" et autres "__fastcall".

Vous n'avez pas ces machins dans vos déclarations de fonctions, ce qui ne pose pas trop de problème quand le code est compilé/compris en C, mais qui part en sucette quand c'est compris comme du C++.

En C, la convention d'appel par défaut, c'est "__cdecl", en C++, c'est "__stdcall". "NTAPI" permet d'indiquer que la convention d'appel est C/__cdecl et non C++/__stdcall.

Dans le header système, la convention est indiqué mais dans votre code, le "NTAPI" est absent, donc gourage dans une configuration C++.

-
Edité par bacelar 21 juin 2018 à 10:25:20

Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
21 juin 2018 à 5:59:25

Merci à tous en modifiant ainsi l'erreur a disparu a la compil....j'ai pas encore tester si le programme tourne j'espere que c'est bon...

KIRQL(NTAPI *KeRaiseIrqlToDpcLevelFix)(void) = &KeRaiseIrqlToDpcLevel;



23 juin 2018 à 4:06:42

j'ai donc corriger ainsi:

__fastcall KfRaiseIrql(    IN KIRQL NewIrql, OUT PKIRQL OldIrql    );

et dans le main:

VOID(__fastcall *KfLowerIrqlFix)( KIRQL NewIrql    ) = &KfLowerIrql;

Est ce correct? En tous cas l'erreur a disparu a la compile?
23 juin 2018 à 20:04:37

Salut,

En fait, les conventions d'appel sont une véritable plaie quand elles se mettent à diverger entre les projet.

Qu'il nous suffise de voir à quoi on est contraint uniquement pour faire la différence entre la compilation (__declspec(dllexport) )et l'utilisation (__declspec(dllimport) )d'une dll de manière relativement simple :p

Par contre, ce qui est chouette, c'est qu'il "suffit" de donner la convention d'appel au moment de déclarer ta fonction pour qu'elle soit correctement prise en compte.

D'un autre coté, créer un alias de type pour ton pointeur de fonction aurait sans doute pas mal d'avantages, en termes de visibilité ;)

j'allais à la base te proposer la solution "barbare" qui consiste à définir un symbole préprocesseur qui donnerait la convention d'appel correcte à tes fonction.  Cela aurait pris une forme proche de

#define CCALL __cdecl

grâce auquel tu aurais pu déclarer chaque fonction susceptible de servir comme callback sous une forme proche de

void CCALL nomFonction(/* paramètres */);

et j'ai failli m'en tenir là ;)

Mais, l'un dans l'autre, il serait sans doute également intéressant de définir l'alias de type sur tes pointeurs de fonctions sous une forme proche de

typedef KIRQL (CCALL * NOM_DU_CALLBACK)(void);

ce qui te permettrait, dans la fonction dans laquelle tu définis quelle fonction doit être appelée, de le faire sous une forme proche de

NOM_DU_CALLBACK cb = &foo;

ou de le passer à une fonction sous une forme proche de

/* soit la fonction */
void /* CCALL*/ bar(NOM_DU_CALLBACK cb){
    /*...*/
}
/* et la fonction à utiliser */
void CCALL foo(void){
    /* .. */
}
int main(){
    bar(&foo);
}

L'idéal étant sans doute, même si plusieurs callbacks prennent les même paramètres et renvoie le même type de donnée, de prévoir un typedef pour chaque comportement (ou famille de comportement) souhaité(e) ;)

-
Edité par koala01 23 juin 2018 à 20:05:12

Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
30 août 2018 à 10:25:45

Merci et désolé pour la reponse tardive.

Fonction pour monter les droits de IRQL à DISPATCH

× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
  • Editeur
  • Markdown