begin process at 2008 08 21 19:23:20
1 229 610 membres
423 nouveaux aujourd'hui
14 263 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

PARAMÈTRES RÉSEAU DIRECTEMENT D'UNE DLL


Information sur la source

Catégorie :API Niveau : Initié Date de création : 17/08/2004 Date de mise à jour : 26/08/2004 18:01:07 Vu : 4 575

Note :
10 / 10 - par 1 personne
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (3)
Ajouter un commentaire et/ou une note

Description

Dans ce source, je reprends l'idée de "DeadlyPredator" pour montrer l'utilité de l'appel direct des fonctions d'une DLL par pointeurs. Voici un exemple de problème résolu grâce à cette méthode:
Pour récuperer l'adresse MAC d'une carte réseau, il y a 3 façons connues mais peu convaicantes:
1- En utilisant le NetBIOS: Nécessite l'installation du partage de fichier et imprimantes.
2- En utilisant l'UUID : Ne fonctionne pas normalement si on a plus d'une interface réseau.
3- En appelant l'API GetAdaptersInfo: Nécessite le téléchargement de la platforme SDK (400 Mo) puis l'installer pour obtenir les fichiers ".h" et ".lib" nécessaires.

La solution idéale est d'appeler directement la DLL du système d'exploitation "iphlpapi.dll". Elle contient toutes les fonctions relatives au paramétrage réseau. Dans ce source, on appelle la fonction GetAdapersInfo() par un pointeur. Pour y arriver, il suffit de définir les structures utilisées, définir le mode d'appel de la fonction , charger la DLL en mémoire et obtenir un pointeur sur la fonction voulue. Cette fonction met tous les paramètres de chaque interface réseau (carte ethernet ou modem) installée sur le système dans une structure spéciale. On récupère ensuite ce qu'on veut de cette structure. Cette solution présente aussi l'avantage d'être compatible avec Windows 98,ME,2000 et XP.
Ce source est pour Visual c++ 6, mais je pense que ça marchera avec les autres compilateurs.

Source

  • //------------------------------------------------------------------------------------------
  • // Créer un projet "Console" vide puis copier-coller ce code.
  • #include <Windows.h>
  • #include <stdio.h>
  • //************ DEBUT DEFINITION DES STRUCTURES ****************
  • //Ce sont des structures standard fournies par Microsoft dans son site MSDN
  • typedef struct {
  • char String[4 * 4];
  • } IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
  • typedef struct _IP_ADDR_STRING {
  • struct _IP_ADDR_STRING* Next;
  • IP_ADDRESS_STRING IpAddress;
  • IP_MASK_STRING IpMask;
  • DWORD Context;
  • } IP_ADDR_STRING, *PIP_ADDR_STRING;
  • typedef struct _IP_ADAPTER_INFO {
  • struct _IP_ADAPTER_INFO* Next;
  • DWORD ComboIndex;
  • char AdapterName[260];
  • char Description[132];
  • UINT AddressLength;
  • BYTE Address[8];
  • DWORD Index;
  • UINT Type;
  • UINT DhcpEnabled;
  • PIP_ADDR_STRING CurrentIpAddress;
  • IP_ADDR_STRING IpAddressList;
  • IP_ADDR_STRING GatewayList;
  • IP_ADDR_STRING DhcpServer;
  • BOOL HaveWins;
  • IP_ADDR_STRING PrimaryWinsServer;
  • IP_ADDR_STRING SecondaryWinsServer;
  • long LeaseObtained; //ici j'ai remplacé "time_t" par "long" pour se passer de "time.h"
  • long LeaseExpires; //idem
  • } IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;
  • //************ FIN DEFINITION DES STRUCTURES ****************
  • int ParamReseau()
  • {
  • //Definir le mode d'appel de fonction par pointeur
  • typedef DWORD (WINAPI *PFONCTION)(PIP_ADAPTER_INFO, PULONG);
  • //Charger la DLL en mémoire
  • HINSTANCE hDLL = LoadLibrary("Iphlpapi.dll");
  • //si problème de chargement de la DLL alors erreur puis quitter
  • if(hDLL==NULL)
  • {
  • printf("%s\n","Erreur chargement iphlp.dll");
  • //attendre l'appui sur ENTREE
  • printf ("%s","Taper ENTREE pour quitter");
  • getchar();
  • return 1;
  • }
  • //Obtenir un pointeur sur la fonction voulue
  • PFONCTION GetAdaptersInfo = (PFONCTION) GetProcAddress(hDLL, "GetAdaptersInfo");
  • //définir le nombre maximum d'interfaces réseau. On peut l'augmenter.
  • int const nombre=3;
  • //Réserver un tableau pour accueillir les données.
  • IP_ADAPTER_INFO infos[nombre];
  • //Déterminer la taille du tableau en octets
  • ULONG taille = sizeof(infos);
  • //Déclarer et initialiser un pointeur sur la variable taille
  • PULONG ptaille=&taille;
  • //Appel de la fonction GetAdaptersInfo()
  • DWORD retour = GetAdaptersInfo (infos, ptaille);
  • //Libérer la DLL de la mémoire
  • FreeLibrary(hDLL);
  • //S'il y'avait erreur alors afficher erreur puis quitter
  • if (retour != ERROR_SUCCESS)
  • {
  • printf("%s\n\n","Aucune information trouvee");
  • //attendre l'appui sur ENTREE
  • printf ("%s","Taper ENTREE pour quitter");
  • getchar();
  • return 1;
  • }
  • //Si tout va bien alors afficher les infos a l'ecran
  • for(int i=0;i<nombre;i++)
  • {
  • printf("%s%d\n"," Interface Numero : ",i);
  • printf("%s%s\n"," Nom : ",infos[i].Description);
  • printf("%s%02X-%02X-%02X-%02X-%02X-%02X\n"," Adresse MAC : ",
  • infos[i].Address[0],infos[i].Address[1],infos[i].Address[2],
  • infos[i].Address[3],infos[i].Address[4],infos[i].Address[5]);
  • printf("%s%s\n"," Adresse IP : ",infos[i].IpAddressList.IpAddress.String);
  • printf("%s%s\n"," Masque sous-reseau : ",infos[i].IpAddressList.IpMask.String);
  • printf("%s%s\n\n"," Passerelle : ",infos[i].GatewayList.IpAddress.String);
  • //s'il n'y a plus d'interface alors sortir de la boucle
  • if (infos[i].Next==NULL) break;
  • }
  • //attendre l'appui sur ENTREE
  • printf ("%s","Taper ENTREE pour quitter");
  • getchar();
  • return 0;
  • }
  • void main ()
  • {
  • ParamReseau();
  • }
  • //------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------
// Créer un projet "Console" vide puis copier-coller ce code.

#include <Windows.h>
#include <stdio.h>

//************ DEBUT DEFINITION DES STRUCTURES ****************
//Ce sont des structures standard fournies par Microsoft dans son site MSDN
typedef struct {
    char String[4 * 4];
} IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;

typedef struct _IP_ADDR_STRING {
    struct _IP_ADDR_STRING* Next;
    IP_ADDRESS_STRING IpAddress;
    IP_MASK_STRING IpMask;
    DWORD Context;
} IP_ADDR_STRING, *PIP_ADDR_STRING;


typedef struct _IP_ADAPTER_INFO {
    struct _IP_ADAPTER_INFO* Next;
    DWORD ComboIndex;
    char AdapterName[260];
    char Description[132];
    UINT AddressLength;
    BYTE Address[8];
    DWORD Index;
    UINT Type;
    UINT DhcpEnabled;
    PIP_ADDR_STRING CurrentIpAddress;
    IP_ADDR_STRING IpAddressList;
    IP_ADDR_STRING GatewayList;
    IP_ADDR_STRING DhcpServer;
    BOOL HaveWins;
    IP_ADDR_STRING PrimaryWinsServer;
    IP_ADDR_STRING SecondaryWinsServer;
    long LeaseObtained; //ici j'ai remplacé "time_t" par "long" pour se passer de "time.h"
    long LeaseExpires;  //idem
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;
//************ FIN DEFINITION DES STRUCTURES ****************


int ParamReseau()
{
    //Definir le mode d'appel de fonction par pointeur
    typedef DWORD (WINAPI *PFONCTION)(PIP_ADAPTER_INFO, PULONG);

    //Charger la DLL en mémoire
    HINSTANCE hDLL = LoadLibrary("Iphlpapi.dll");

    //si problème de chargement de la DLL   alors erreur puis quitter
    if(hDLL==NULL)
    {
        printf("%s\n","Erreur chargement iphlp.dll");

        //attendre l'appui sur ENTREE
        printf ("%s","Taper ENTREE pour quitter");
        getchar();
        return 1;
    }

    //Obtenir un pointeur sur la fonction voulue
    PFONCTION GetAdaptersInfo = (PFONCTION) GetProcAddress(hDLL, "GetAdaptersInfo");
    
    //définir le nombre maximum d'interfaces réseau. On peut l'augmenter.
    int const nombre=3;

    //Réserver un tableau pour accueillir les données.
    IP_ADAPTER_INFO infos[nombre];
    
    //Déterminer la taille du tableau en octets
    ULONG taille = sizeof(infos);

    //Déclarer et initialiser un pointeur sur la variable taille
    PULONG ptaille=&taille;
    
    //Appel de la fonction GetAdaptersInfo()
    DWORD retour = GetAdaptersInfo (infos, ptaille);
    
    //Libérer la DLL de la mémoire
    FreeLibrary(hDLL);

    //S'il y'avait erreur alors afficher erreur puis quitter
    if (retour != ERROR_SUCCESS)
    {
        printf("%s\n\n","Aucune information trouvee");

        //attendre l'appui sur ENTREE
        printf ("%s","Taper ENTREE pour quitter");
        getchar();
        return 1;
    }
    
    //Si tout va bien alors afficher les infos a l'ecran
    for(int i=0;i<nombre;i++)
    {
    printf("%s%d\n","  Interface Numero : ",i);
    printf("%s%s\n","         Nom : ",infos[i].Description);
    printf("%s%02X-%02X-%02X-%02X-%02X-%02X\n","     Adresse MAC : ",
         infos[i].Address[0],infos[i].Address[1],infos[i].Address[2],
         infos[i].Address[3],infos[i].Address[4],infos[i].Address[5]);
    printf("%s%s\n","      Adresse IP : ",infos[i].IpAddressList.IpAddress.String);
    printf("%s%s\n","  Masque sous-reseau : ",infos[i].IpAddressList.IpMask.String);
    printf("%s%s\n\n","      Passerelle : ",infos[i].GatewayList.IpAddress.String);

    //s'il n'y a plus d'interface alors sortir de la boucle
    if (infos[i].Next==NULL) break;
    
    }
    
    //attendre l'appui sur ENTREE
    printf ("%s","Taper ENTREE pour quitter");
    getchar();
    return 0;
                
}

void main ()
{
    ParamReseau();
}
//------------------------------------------------------------------------------------------

Conclusion

Voilà, j'espère n'avoir rien oublié. Très bientôt, je posterai une version plus complète pour Windows. En attendant, vos questions, commentaires, remarques ou critiques sont les bienvenus. A+
26 août 2004 18:01:07 :
  • signaler à un administrateur
    Commentaire de DeadlyPredator le 17/08/2004 06:46:53

    C'est vrai que ça fait un bon exemple MAIS n'oublis pas qu'avec ma méthode, l'API ce trouve ralentie car elle n'est pas appellée directement comme c'est le cas quand on a le fichier ".lib".

  • signaler à un administrateur
    Commentaire de racpp le 17/08/2004 15:23:07 administrateur CS

    Salut,
    C'est une bonne remarque, mais  je pense que l'API est toujours appelée directement pendant l'exécution du programme par son adresse mémoire et en passant les paramètres dans la pile. La définition du mode d'appel n'est utile que pour  le compilateur. Que ce soit dans un .LIB  ou par pointeur le résultat  est le même. Mais j'aimerais bien voir l'avis de quelqu'un qui  a fait des tests réels pour en avoir le coeur net. Si tu l'as déja fait,  donne moi un exemple de petit source (ou un lien) illustrant la différence entre les deux méthodes. Merci.
    A bientôt.

  • signaler à un administrateur
    Commentaire de lchanpat le 14/06/2005 13:46:07

    La différence entre la lib et l'accès direct est que LoadModule est éxécuté implicitement au chargement du processus.  Dans le cas du .lib, celui-ci doit donc "trainer" dans sa mémoire une dll dont l'accès n'est fait qu'une fois, et son temps de chargement sera affecté.
    Dans le cas de l'accès direct, il faudra traiter le cas de la dll non présente, et prévoir un bref délai de chargement|déchargement.
    Les deux méthode sont bonnes, le développeur choisira donc en fonction de l'application finale.

    Sinon : code bon, bien indenté, bien commenté = bonne note.

    Merci

Ajouter un commentaire

Pub



Appels d'offres

CalendriCode

Août 2008
LMMJVSD
    123
45678910
11121314151617
18192021222324
25262728293031

Boutique

Boutique de goodies CodeS-SourceS