64 bits loopt door onduidelijke reden vast

Status
Niet open voor verdere reacties.

sanders1969

Gebruiker
Lid geworden
29 dec 2018
Berichten
243
Ik heb een functie: MD5Hash en ik heb keurig de 64 bits onderscheden van de 32 bits echter gaat er op een 64 bits office over zn nek bij de laatste regel: rngdata2 = StrConv(rngdata, vbFromUnicode)
"StrConv" wordt niet herkent. Ziet iemand meteen wat ik kennelijk fout doe?
Ik heb dezelfde applicatie op een ander 64 bits office draaien en daar gaat het gewoon goed dus begrijp niet waarom ie over de zeik is.

Code:
Option Compare Database
#If Win64 Then

Declare PtrSafe Function CryptAcquireContext Lib "advapi32" Alias "CryptAcquireContextA" (ByRef hProv As Long, ByVal sContainer As String, ByVal sProvider As String, ByVal lProvType As Long, ByVal lFlags As Long) As Long

Declare PtrSafe Function CryptCreateHash Lib "advapi32" (ByVal hProv As Long, ByVal lALG_ID As Long, ByVal hKey As Long, ByVal lFlags As Long, ByRef hhash As Long) As Long

Declare PtrSafe Function CryptHashData Lib "advapi32" (ByVal hhash As Long, ByVal lDataPtr As Long, ByVal lLen As Long, ByVal lFlags As Long) As Long

Declare PtrSafe Function CryptGetHashParam Lib "advapi32" (ByVal hhash As Long, ByVal lParam As Long, ByVal sBuffer As String, ByRef lLen As Long, ByVal lFlags As Long) As Long

Declare PtrSafe Function CryptDestroyHash Lib "advapi32" (ByVal hhash As Long) As Long

Declare PtrSafe Function CryptReleaseContext Lib "advapi32" (ByVal hProv As Long, ByVal lFlags As Long) As Long

#Else

Declare Function CryptAcquireContext Lib "advapi32" Alias "CryptAcquireContextA" (ByRef hProv As Long, ByVal sContainer As String, ByVal sProvider As String, ByVal lProvType As Long, ByVal lFlags As Long) As Long

Declare Function CryptCreateHash Lib "advapi32" (ByVal hProv As Long, ByVal lALG_ID As Long, ByVal hKey As Long, ByVal lFlags As Long, ByRef hhash As Long) As Long

Declare Function CryptHashData Lib "advapi32" (ByVal hhash As Long, ByVal lDataPtr As Long, ByVal lLen As Long, ByVal lFlags As Long) As Long

Declare Function CryptGetHashParam Lib "advapi32" (ByVal hhash As Long, ByVal lParam As Long, ByVal sBuffer As String, ByRef lLen As Long, ByVal lFlags As Long) As Long

Declare Function CryptDestroyHash Lib "advapi32" (ByVal hhash As Long) As Long

Declare Function CryptReleaseContext Lib "advapi32" (ByVal hProv As Long, ByVal lFlags As Long) As Long

#End If

Const MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0"
Const PROV_RSA_FULL As Long = 1
Const CRYPT_NEWKEYSET As Long = 8
Const CALG_MD5 As Long = 32771
Const HP_HASHVAL As Long = 2

Public Function MD5Hash(rngdata) As String
    Dim rngdata2 As String
    Dim hProv As Long
    Dim hhash As Long
    Dim lLen As Long
    Dim sBuffer As String
    Dim sBuffer2 As String
    Dim lresult As Long
    Dim i As Long
    
    CryptAcquireContext hProv, vbNullString, MS_DEF_PROV, PROV_RSA_FULL, 0
    If hProv = 0 Then
        CryptAcquireContext hProv, vbNullString, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET
    End If
    If hProv <> 0 Then
        CryptCreateHash hProv, CALG_MD5, 0, 0, hhash
        If hhash <> 0 Then
            rngdata2 = StrConv(rngdata, vbFromUnicode)
 
Missen we niet een stuk code? En wellicht is een voorbeeld van de db een stuk makkelijker, omdat ik dan kan kijken of hij bij mij wél werkt.
 
Dit is het volledige, hopen dat ie bij jou over zn nek gaat.
Vage is dat deze code eerder bij een ander office 365 64 bits gewoon goed ging.

Code:
Option Compare Database
#If Win64 Then

Declare PtrSafe Function CryptAcquireContext Lib "advapi32" Alias "CryptAcquireContextA" (ByRef hProv As Long, ByVal sContainer As String, ByVal sProvider As String, ByVal lProvType As Long, ByVal lFlags As Long) As Long

Declare PtrSafe Function CryptCreateHash Lib "advapi32" (ByVal hProv As Long, ByVal lALG_ID As Long, ByVal hKey As Long, ByVal lFlags As Long, ByRef hhash As Long) As Long

Declare PtrSafe Function CryptHashData Lib "advapi32" (ByVal hhash As Long, ByVal lDataPtr As Long, ByVal lLen As Long, ByVal lFlags As Long) As Long

Declare PtrSafe Function CryptGetHashParam Lib "advapi32" (ByVal hhash As Long, ByVal lParam As Long, ByVal sBuffer As String, ByRef lLen As Long, ByVal lFlags As Long) As Long

Declare PtrSafe Function CryptDestroyHash Lib "advapi32" (ByVal hhash As Long) As Long

Declare PtrSafe Function CryptReleaseContext Lib "advapi32" (ByVal hProv As Long, ByVal lFlags As Long) As Long

#Else

Declare Function CryptAcquireContext Lib "advapi32" Alias "CryptAcquireContextA" (ByRef hProv As Long, ByVal sContainer As String, ByVal sProvider As String, ByVal lProvType As Long, ByVal lFlags As Long) As Long

Declare Function CryptCreateHash Lib "advapi32" (ByVal hProv As Long, ByVal lALG_ID As Long, ByVal hKey As Long, ByVal lFlags As Long, ByRef hhash As Long) As Long

Declare Function CryptHashData Lib "advapi32" (ByVal hhash As Long, ByVal lDataPtr As Long, ByVal lLen As Long, ByVal lFlags As Long) As Long

Declare Function CryptGetHashParam Lib "advapi32" (ByVal hhash As Long, ByVal lParam As Long, ByVal sBuffer As String, ByRef lLen As Long, ByVal lFlags As Long) As Long

Declare Function CryptDestroyHash Lib "advapi32" (ByVal hhash As Long) As Long

Declare Function CryptReleaseContext Lib "advapi32" (ByVal hProv As Long, ByVal lFlags As Long) As Long

#End If

Const MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0"
Const PROV_RSA_FULL As Long = 1
Const CRYPT_NEWKEYSET As Long = 8
Const CALG_MD5 As Long = 32771
Const HP_HASHVAL As Long = 2

Public Function MD5Hash(rngdata) As String
    Dim rngdata2 As String
    Dim hProv As Long
    Dim hhash As Long
    Dim lLen As Long
    Dim sBuffer As String
    Dim sBuffer2 As String
    Dim lresult As Long
    Dim i As Long
    
    CryptAcquireContext hProv, vbNullString, MS_DEF_PROV, PROV_RSA_FULL, 0
    If hProv = 0 Then
        CryptAcquireContext hProv, vbNullString, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET
    End If
    If hProv <> 0 Then
        CryptCreateHash hProv, CALG_MD5, 0, 0, hhash
        If hhash <> 0 Then
            rngdata2 = StrConv(rngdata, vbFromUnicode)
            lresult = CryptHashData(hhash, StrPtr(rngdata2), LenB(rngdata2), 0&)
            sBuffer = Space(16)
            lLen = 16
            CryptGetHashParam hhash, HP_HASHVAL, sBuffer, lLen, 0
            For i = 1 To 16
                sBuffer2 = Hex(Asc(Mid(sBuffer, i, 1)))
                If Len(sBuffer2) <> 2 Then
                    MD5Hash = MD5Hash + "0" + sBuffer2
                Else
                    MD5Hash = MD5Hash + sBuffer2
                End If
            Next
            CryptDestroyHash hhash
        End If
        CryptReleaseContext hProv, 0
    End If
    
End Function
 
En hoe gebruik je die code?
 
Gaat over de zeik betekend? Loopt vast of krijg je een foutmelding?
 
@vena: Lees bericht 1 nog eens, daar wordt het al uitgelegd :).
 
In bericht 1 wordt niets uitgelegd wat met mijn vragen te maken heeft. Beetje beter lezen. Er staat alleen dat StrConv niet herkent wordt. Maar ja is het ACCESS alias OctaFish forum zeker.
 
Ik ben het met @VenA eens dat het niet duidelijk is wat er precies fout gaat.
Komt er een foutmelding (zo ja, welke?) of is er wat anders aan de hand? Als de code wordt gecompileerd geeft deze dan ook een foutmelding?

Hoe dan ook, als het fout gaat, dan zou ik wel eens de waarde van variable rngdata willen zien.

Daarnaast zie ik dat het aanpassen van de functies naar 64 bit niet helemaal goed is gegaan. Dit kan ook een reden van de problemen zijn. In de eerste plaats wordt gebruik gemaakt van compilerconstante Win64. Dat is eigenlijk niet juist. Beter is om gebuik te maken van conditional compiler constante VBA7. Dus #If VBA7 i.p.v. #If Win64. Bij het gebuik van VBA7 betekent het dat het Else-statement wordt uitgevoerd bij office versies ouder dan 2010. Als deze applicatie helemaal niet hoeft te draaien in 2007 of ouder, dan is in dit geval het gebruik van compiler constanten helemaal niet nodig. Win64 gebruik je eigenlijk alleen als in de 64 bits omgeving de naam van de aan te roepen functie anders is. Dit komt niet heel veel voor (bijv GetTickCount en GetTickCount64).

Het aanpassen naar 64 bit is niet altijd alleen een kwestie van het toevoegen van PtrSafe. PtrSafe doet in feite eigenlijk helemaal niks. Het enige dat je daarmee aan de compiler 'vertelt' is dat de gebruikte variabelen allemaal gecheckt zijn voor gebruikt in 64 bit. Maar in dit geval moeten ook meerdere variabelen aangepast worden. Ik heb ze niet allemaal bekeken, maar in de eerste functie moet bijvoorbeeld variabele hProv geen Long zijn, maar een LongPtr. Een LongPtr is in 32 bit omgeving een Long en in 64 bit omgeving een LongLong. Er zijn nog meer variabelen die zo moeten worden aangepast. Als variabelen niet goed zijn geconfigureerd voor 64 bit dan kan dat problemen geven, zoals vastlopers, onvoorspelbaar gedrag en foutmeldingen.

Ook zijn er mogelijkheden om een MD5 hash te genereren zonder gebruik te maken van API calls. Zie bijvoorbeeld onderstaande links. Ik heb dit verder niet uitgebreid bekeken, maar wellicht dat je er wat mee kunt.
https://gist.github.com/ken-itakura/c35455bccbae1544189e37b713698b75
https://en.wikibooks.org/wiki/Visual_Basic_for_Applications/String_Hashing_in_VBA
 
Laatst bewerkt:
In bericht 1 wordt niets uitgelegd wat met mijn vragen te maken heeft. Beetje beter lezen.
??? Je stelt helemaal geen vragen, anders dan dat je je afvraagt wat de betekenis is van 'over de zeik' is. Daarnaast is het natuurlijk altijd leuk(?) om mij af te zeiken. Ga daar vooral mee door, je doet daar een hoop mensen een plezier mee!

Als een code (maakt niet uit in welk forum of programma) 'over de zeik gaat' over een regel, dan stopt hij daar. Dat zou je zelf ook moeten weten. Dat TS iets 'technischer' had mogen zijn, is uiteraard wel wenselijk, al vermoed ik dat er geen foutmelding aan te pas komt, als de code gewoon stopt en de VBA regel geel markeert.

Gelukkig is de bijdrage van rebmog wél nuttig en ter zake doende :).
 
Let wel op als je ASCII character codes (0-127) of ANSI (0-255) gebruikt.
Code:
textBytes = textString
kan dan overwachte dingen doen.
Dus eerst grondig testen met verschillende PC's en verschillende strings.
MD5Hash is voor controles, en als de helft van de controlers niet klopt omdat de basis niet goed is, is dat jammer.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan