Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

de l'aide pour comprendre un module

3 réponses
Avatar
squat541
salut a tous
voici le module
Const SOCKET_ERROR = 0
Private Type WSAData
wVersion As Integer
wHighVersion As Integer
szDescription(0 To 255) As Byte
szSystemStatus(0 To 128) As Byte
iMaxSockets As Integer
iMaxUdpDg As Integer
lpVendorInfo As Long
End Type
Private Type Hostent
h_name As Long
h_aliases As Long
h_addrtype As Integer
h_length As Integer
h_addr_list As Long
End Type
Private Type IP_OPTION_INFORMATION
TTL As Byte
Tos As Byte
Flags As Byte
OptionsSize As Long
OptionsData As String * 128
End Type
Private Type IP_ECHO_REPLY
Address(0 To 3) As Byte
Status As Long
RoundTripTime As Long
DataSize As Integer
Reserved As Integer
Data As Long
Options As IP_OPTION_INFORMATION
End Type
Private Declare Function GetHostByName Lib "wsock32.dll" Alias
"gethostbyname" (ByVal HostName As String) As Long
Private Declare Function WSAStartup Lib "wsock32.dll" (ByVal
wVersionRequired&, lpWSADATA As WSAData) As Long
Private Declare Function WSACleanup Lib "wsock32.dll" () As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest
As Any, hpvSource As Any, ByVal cbCopy As Long)
Private Declare Function IcmpCreateFile Lib "icmp.dll" () As Long
Private Declare Function IcmpCloseHandle Lib "icmp.dll" (ByVal HANDLE As
Long) As Boolean
Private Declare Function IcmpSendEcho Lib "ICMP" (ByVal IcmpHandle As Long,
ByVal DestAddress As Long, ByVal RequestData As String, ByVal RequestSize As
Integer, RequestOptns As IP_OPTION_INFORMATION, ReplyBuffer As IP_ECHO_REPLY,
ByVal ReplySize As Long, ByVal TimeOut As Long) As Boolean



Public Function Echo(Ip As String) As String
'KPD-Team 2000
'URL: http://www.allapi.net/
'E-Mail: KPDTeam@Allapi.net
'Const HostName = "192.168.0.101"
Dim HostName As String
HostName = Ip
Dim hFile As Long, lpWSADATA As WSAData
Dim hHostent As Hostent, AddrList As Long
Dim Address As Long, rIP As String
Dim OptInfo As IP_OPTION_INFORMATION
Dim EchoReply As IP_ECHO_REPLY
Call WSAStartup(&H101, lpWSADATA)
If GetHostByName(HostName + String(64 - Len(HostName), 0)) <>
SOCKET_ERROR Then
CopyMemory hHostent.h_name, ByVal GetHostByName(HostName + String(64
- Len(HostName), 0)), Len(hHostent)
CopyMemory AddrList, ByVal hHostent.h_addr_list, 4
CopyMemory Address, ByVal AddrList, 4
End If
hFile = IcmpCreateFile()
If hFile = 0 Then
MsgBox "Unable to Create File Handle"
Exit Function
End If
OptInfo.TTL = 255
DoEvents
If IcmpSendEcho(hFile, Address, String(32, "A"), 32, OptInfo, EchoReply,
Len(EchoReply) + 8, 2000) Then
rIP = CStr(EchoReply.Address(0)) + "." + CStr(EchoReply.Address(1))
+ "." + CStr(EchoReply.Address(2)) + "." + CStr(EchoReply.Address(3))
Else
'MsgBox "Timeout"
Echo = "Failure"
End If
If EchoReply.Status = 0 Then
'MsgBox "Reply from " + HostName + " (" + rIP + ") recieved after "
+ Trim$(CStr(EchoReply.RoundTripTime)) + "ms"
Echo = Trim$(CStr(EchoReply.RoundTripTime))
Else
'MsgBox "Failure ..."
End If
Call IcmpCloseHandle(hFile)
Call WSACleanup
End Function

je c qu'il sert a faire des ping mais je ne sais commen si quelqu'un pourrai
me l'expliquer

3 réponses

Avatar
Thierry BERTRAND
On passe sur les déclarations des API.

Principe du programme:
On va envoyer une requète ICMP (protocole standard réseau) vers la machine
voulue, tester le status de retour et le temps de parcours.
cela s'effectue via la primitive ICMPSendEcho.

Cette primitive demande un handle qui est créé avec la primitie
ICMPCreateFile, et libéré par la primitive ICMPCloseHandle. Pas de
commentaire, c'est comme ça.

Par contre, problème, cette primitive (ICMPSendEcho) demande une adresse
d'un emplacement mémoire où se trouvera l'adresse IP sous forme interne. (Si
IP V6, le format n'est pas le meme que IP "classique")
Comme en général on connait les machine soit par leur adresse IP sous la
forme d'une chaine "A.B.C.D" ou sous son nom "www.micorsoft.com", il faut
traduite ces chaines de caratère en format interne.
A la limite pour "A.B.C.D" ça pourrai etre simple, mais pour
"www.microsoft.com" on sait pas à priori.
Donc pour cela, on va s'addresser aux primitive windows qui vont permettre,
via le protocole DNS, de transformer une adresse chaine de caratère en une
adresse LONG.

C'est l'objet de la primitive GetHostByName, qui traduit une adresse sous
forme chaine de caractère en une structure interne, contenant, entre autre,
des pointeurs vers l'adresse IP format interne.
L'adresse passée en paramètre peut etre "a.b.c.d" ou "www.microfot.com",
cela marche pareil.
Cette primitive rempli la structure HostEnt qui lui est passée par adresse.
Dans cette structure, le champ h_addr_list contient l'adresse pour la
fameuse valeur cherchée.

La structure renvoyée ne contient pas les valeurs elles-meme, mais une
adresse mémoire (un pointeur sous forme d'un LONG) vers les valeurs. d'omù
les appels à copymemory.

La primitive copymemory permet de transférer directement en mémoire, une
suite d'octet, sans s'inqiéter de son type, en passant les adresses mémoire
des zones. Cela est identique à une affectation, mais pour des variables
dont on ne connait pas forcément la longueur.
D'où les 3 appels à Copymemory pour tranférer en mémoire les valeurs
désirées.

ce qui est intéressant de savoir:

Dans la structure HOSTENT, le champ h_length contient la longueur du champ
h_addr_list, et le champ h_addr_list est une suite d'octets constituant
l'adresse IP de la machine désirée.
D'où le code suivant (à insérer dans le code existant)

Dim temp_ip_address() As Byte
Dim i As Integer
Dim ip_address As String

CopyMemory temp_ip_address(1), hostip_addr, host.hLen
For i = 1 To host.hLen
ip_address = ip_address & temp_ip_address(i) & "."
Next
ip_address = Mid$(ip_address, 1, Len(ip_address) - 1)

qui permet de récupérer l'adrese IP de la machine dont on ne connait que le
nom sous la forme d'une chaine de caratère "a.b.c.d" si IP V4 et
"a.b.c.d.e.f" si IP V6 par exemple.
Avatar
Patrice Henrio
> les appels à copymemory.

La primitive copymemory permet de transférer directement en mémoire, une
suite d'octet, sans s'inqiéter de son type, en passant les adresses
mémoire
des zones. Cela est identique à une affectation, mais pour des variables
dont on ne connait pas forcément la longueur.
D'où les 3 appels à Copymemory pour tranférer en mémoire les valeurs
désirées.



En général pour copymemory il faut connaître le nombre d'octets à transférer
qui peut s'obtenir soit à partir de Len(V) où V est une variable d'un type
donnée soit directement parce que justement on le connait.
Le copymemory va plus vite car il n'y a aucun test de type, contrairement à
une affectation.
De plus pour copier un tableau c'est vraiment super, il n'y a pas à le
parcourir. Il suffit de miltiplier la longueur en octets d'un élément par le
nombre d'éléments.
Avatar
Thierry Bertrand
Merci de la présision sur CopyMemory.
Effectivement, on avait l'impression dans mon message, qu'on ne connaissait
pas la longueur de la zone à copier,
ce qui serait faux bien sûr au moment de l'exécution.

Il fallait lire: dont on ne connait pas toujours à priori la longueur.