Entwickler-Ecke
Windows API - Protokoll installiert? (WSAEnumProtocols)
CodexX - So 17.05.09 18:16
Titel: Protokoll installiert? (WSAEnumProtocols)
Ich möchte gerne prüfen, ob das Ipv6 Protokoll installiert ist. Das sollte mit der Funktion WSAEnumProtocols aus Winsock2 möglich sein. Leider erhalte ich bei genau diesem Aufruf [LCount := WSAEnumProtocols(nil,LPInfo,LLen);] den Fehler "Access violation at address 00000000. Read of address 00000000." Warum? Muss noch irgendetwas initialisiert werden? Oder ganz anders? :?!?:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
| function IPv6Installiert : Boolean; var LLen : LongWord; LPInfo, LPCurPtr : LPWSAProtocol_Info; LCount : Integer; i : Integer; begin Result := False; LLen := 0; WSAEnumProtocols(nil,nil,LLen); GetMem(LPInfo,LLen);
try LCount := WSAEnumProtocols(nil,LPInfo,LLen); if LCount <> SOCKET_ERROR then begin LPCurPtr := LPInfo; for i := 0 to LCount-1 do begin Memo1.Lines.Add(IntToStr(LPCurPtr^.iAddressFamily)); Result := (LPCurPtr^.iAddressFamily=PF_INET6); if Result then begin Break; end; Inc(LPCurPtr); end; end; finally FreeMem(LPInfo); end; end; |
WSAEnumProtocols kommt aus IdWinsock2 (Indy10).
Narses - So 17.05.09 23:22
Moin!
CodexX hat folgendes geschrieben : |
Muss noch irgendetwas initialisiert werden? |
Hab mir das jetzt nicht im Detail angesehen, aber du rufst nirgendwo WSAStartup() auf. :nixweiss:
cu
Narses
CodexX - Mo 18.05.09 03:50
Also ich glaub, ich habs jetzt...
WSAStartup hatte ich ursprünglich in der Funktion drin, habe es aber testweise ausgelagert. (deshalb fehlt das in meinem Beispiel)
Nach dem Posting von BenBE habe ich erstmal nach seinem Vorschlag gesucht und dabei ist mir aufgefallen, dass WSAStartup sowohl in Winsock als auch IdWinsock2 enthalten ist. Da ich beide über uses eingebunden hatte (IdWinsock2 reicht mir leider nicht), wurde aufgrund der Reihenfolge WSAStartup leider aus Winsock genommen und hat dann leider nicht mit WSAEnumProtocols funktioniert. Ich habe jetzt bei der Einbindung deren Plätze getauscht und damit funktioniert das jetzt.
Dein Hinweis ging also genau in die richtige Richtung, Narses.
Insofern danke Euch beiden!
CodexX - Mo 01.06.09 07:41
Doch noch nicht erledigt. Wie ich nun merke, funktioniert die Funktion nur beim ersten Aufruf. Ab dem zweiten leider nicht mehr... Wird das Programm neu gestartet, tut sie wieder genau ein Mal.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38:
| var LLen : LongWord; LPInfo, LPCurPtr : LPWSAProtocol_Info; LCount : Integer; i : Integer; Data: TWSAData; begin Result := False; LLen := 0;
if WSAStartup( MakeWord(2,2), Data) = SOCKET_ERROR then HandleWSAError else begin try WSAEnumProtocols(nil,nil,LLen); GetMem(LPInfo,LLen);
LCount := WSAEnumProtocols(nil,LPInfo,LLen); if LCount <> SOCKET_ERROR then begin LPCurPtr := LPInfo; for i := 0 to LCount-1 do begin Result := (LPCurPtr^.iAddressFamily=PF_INET6); if Result then begin Break; end; Inc(LPCurPtr); end; end; finally WSACleanup; end; end; end; |
Bin es mal durchgegangen und sehe, dass beim zweiten Aufruf der Funktion nach "WSAEnumProtocols(nil,nil,LLen);" LLen = 0 ist.
Warum?? Muss noch irgendwas resetet werden? WSACleanup wird korrekt aufgerufen. Sonst noch was? :?
CodexX - Di 02.06.09 17:50
Kennt sich damit keiner aus? :(
BenBE - Di 02.06.09 19:01
Du hast nicht angegeben, welche Fehlermeldung GetLastError liefert. Und Kristallkugeln sind immer so unglaublich teuer ;-)
CodexX - Di 02.06.09 19:14
Beim ersten Aufruf wie zu erwarten: 0
Beim zweiten Aufruf: 10093 = Either the application has not called WSAStartup, or WSAStartup failed.
Allerdings ist WSAStartup( MakeWord(2,2), Data) = SOCKET_ERROR sowohl beim ersten als auch beim zweiten Aufruf false (der else-Block wird verarbeitet), sodass eigentlich kein Fehler vorhanden sein sollte. :/
BenBE - Di 02.06.09 19:36
Wenn ich das richtig im Überblick hatte, so durfte WSAStartup insgesamt im Prozessverlauf nur einmal aufgerufen werden. Genau kann Dir das aber wahrscheinlich
Narses am Besten sagen.
Narses - Do 04.06.09 17:54
Moin!
BenBE hat folgendes geschrieben : |
Wenn ich das richtig im Überblick hatte, so durfte WSAStartup insgesamt im Prozessverlauf nur einmal aufgerufen werden. |
In der Regel macht es keinen Sinn, mehrfach WSAStartup() aufzurufen, aber verboten scheint es nicht zu sein:
WinSock2.hlp hat folgendes geschrieben: |
An application or DLL may call WSAStartup more than once if it needs to obtain the WSAData structure information more than once. On each such call the application may specify any version number supported by the DLL.
There must be one WSACleanup call corresponding to every successful WSAStartup call to allow third-party DLLs to make use of a Windows Sockets DLL on behalf of an application. This means, for example, that if an application calls WSAStartup three times, it must call WSACleanup three times. The first two calls to WSACleanup do nothing except decrement an internal counter; the final WSACleanup call for the task does all necessary resource deallocation for the task. |
Genaueres sagt dir aber bestimmt das MSDN.
WSASTARTUP
cu
Narses
CodexX - So 07.06.09 16:11
Der Fehler liegt scheinbar bei Indy10. Ich habe testweise stattdessen die Jedi Winsock2-Übersetzung (JwaWinsock2) genommen und damit tritt der Fehler nicht auf. Ich werde es aber noch etwas genauer testen.
Das also mal als Hinweis an alle, die in dem Bereich was machen und ähnliche Probleme haben sollten.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!