Paramètres réseau directement d'une dll

Contenu du snippet

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 / Exemple :


//------------------------------------------------------------------------------------------
// 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+

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.