extern "C" __declspec(dllexport) int GetHash(HASHINFO*);
Code:
typedef struct {
unsigned char* pHash; // Address of buffer for saving hash
unsigned char* szPassword; // Password
int nPasswordLen; // Password length
unsigned char* szSalt; // Salt
int nSaltLen; // Salt length
unsigned char* szName; // User name
int nNameLen; // User name length
DWORD dwFlags; // Flags
} HASHINFO;
Here is the VB
Code:
Private Type HASHINFO
hash As String
szPassword As String * 10
nPasswordLen As Long
szSalt As String * 10
nSaltLen As Long
szName As String * 10
nNameLen As Long
dwFlags As Long
End Type
Private Declare Sub GetHash Lib "c:\md5\md5.dll" (ByRef pudt As HASHINFO)
Code:
Private Sub Command1_Click()
Dim udt As HASHINFO
udt.hash = vbNullString
udt.szPassword = "test" & Chr(0)
udt.nNameLen = 4
udt.szSalt = "test" & Chr(0)
udt.nSaltLen = 4
udt.szName = "test" & Chr(0)
udt.nNameLen = 4
udt.dwFlags = 0
Call GetHash(udt)
End Sub
I just get a crash.
Anyone out there to help me?
Last edited by GremlinSA; July 10th, 2012 at 03:58 AM.
typedef struct {
unsigned char* pHash; // Address of buffer for saving hash <-- Variable Length
unsigned char* szPassword; // Password <-- Variable Length
int nPasswordLen; // Password length <-- Defined length of char array
unsigned char* szSalt; // Salt <-- Variable Length
int nSaltLen; // Salt length <-- Defined length of char array
unsigned char* szName; // User name <-- Variable Length
int nNameLen; // User name length <-- Defined length of char array
DWORD dwFlags; // Flags
} HASHINFO;
Code:
Private Type HASHINFO
hash As String '<--- Variable Length
szPassword As String * 10 '<--- Fixed Length
nPasswordLen As Long
szSalt As String * 10 '<--- Fixed Length
nSaltLen As Long
szName As String * 10 '<--- Fixed Length
nNameLen As Long
dwFlags As Long
End Type
Made a few pointers here ... Notice what i'm pointing out...
Another one is ..
C++ Int = 4 bytes..
VB6 Long = 8 Bytes..
Your two data types need to match up exactly, so that the External C DLL can correctly parse out the info .
Code:
Private Sub Command1_Click()
Dim udt As HASHINFO
udt.hash = vbNullString
udt.szPassword = "test" & Chr(0) ' <-- using 5 of the 10 allocated..
udt.nNameLen = 4 ' <--- Wrong Variable used in here......
udt.szSalt = "test" & Chr(0) ' <-- using 5 of the 10 allocated..
udt.nSaltLen = 4 ' <-- Saying Prev Char is only 4 long when its defined as 10 long..
udt.szName = "test" & Chr(0) ' same here
udt.nNameLen = 4 ' Same Here...
udt.dwFlags = 0
Call GetHash(udt)
End Sub
I'm pretty sure VB Long is 4 bytes, Double is 8 bytes.
I have tried this
Code:
Public Type HASHINFO
pHash As String
szPassword As String
nPasswordLen As Long
szSalt As String
nSaltLen As Long
szName As String
nNameLen As Long
dwFlags As Long
End Type
Public Declare Function GetHash Lib "C:\md5\md5.dll" (ByRef xx As HASHINFO) As Long
Call code:
Code:
Private Sub Command1_Click()
Dim test as long
Dim udt As HASHINFO
udt.szPassword = "test"
udt.nPasswordLen = 4
udt.szSalt = "test"
udt.nSaltLen = 4
udt.szName = "test"
udt.nNameLen = 4
udt.dwFlags = &H0
test = GetHash(udt)
End Sub
I'm not sure if I need to specify something for udt.pHash, have tried various things and it still crashes.
I'm pretty sure VB Long is 4 bytes, Double is 8 bytes.
you actually are right.. VB.NET Long = 8 bytes in VB6 = 4 bytes.. Havn't done VB6 in a long time..
Originally Posted by user65536
I have tried this
Code:
Public Type HASHINFO
pHash As String
szPassword As String
nPasswordLen As Long
szSalt As String
nSaltLen As Long
szName As String
nNameLen As Long
dwFlags As Long
End Type
Dim udt As HASHINFO
udt.szPassword = "test"
udt.nPasswordLen = 4
udt.szSalt = "test"
udt.nSaltLen = 4
udt.szName = "test"
udt.nNameLen = 4
udt.dwFlags = &H0
test = GetHash(udt)
End Sub
I'm not sure if I need to specify something for udt.pHash, have tried various things and it still crashes.
You will need to assign the right amount of space for the Hash to be put in (32 Byte hash ?) as the C DLL cannot assign new/ more memory to the referenced Datatype.
You were on the right track with the Null (&H0) termination..
But something else i'm thinking is that VB stores stings in Unicode (2 bytes per char) and the char array in C is expecting one byte per char.. (this may need clarification from a C Expert) ...
in this case an array of byte may be better to use, and you load the ASCII val of each char in the string to the byte array..
You will have to play with it a little, if your Defs and Variable lengths are out by one, it will crash ...
try this for debugging
Code:
Debug.print len(udt)
After you've assigned all the values and then see if it matches what you should have...
In my opinion the strings in the UDT should either be of fixed length or, if dynamic, they must be initialized.
If you expect a string to be filled in by the dll yo must provide enough buffer space for the resulting string.
If udt.pHash is the string where you expect the result to be returned, you have to preallocate space like
Code:
Private Sub Command1_Click()
Dim test as long
Dim udt As HASHINFO
udt.pHash = Space$(256) '<---- preallocate a buffer of 256 characters
udt.szPassword = "test"
udt.nPasswordLen = 4
udt.szSalt = "test"
udt.nSaltLen = 4
udt.szName = "test"
udt.nNameLen = 4
udt.dwFlags = &H0
test = GetHash(udt)
End Sub
If this fails you try to declare pHash as a constant length string, like in your first version you did with the other strings
Code:
Public Type HASHINFO
pHash As String * 256
....
The length of the string depends on how many characters you expect to be returned.
in order to determine how many bytes pHash is suppose to be buffered the dll call was attempted in c.
It appears that only
szPassword
nPasswordLen
are the necessary inputs
while pHash returns a Byte Array of (16 bytes), this byte array needs to be then converted to hex to give the full 32byte hexstring of the hash.
The VB Code was then modified to reflect this.
Code:
Private Sub Command1_Click()
Dim test as long
Dim udt As HASHINFO
udt.pHash = Space$(16)
udt.szPassword = "test"
udt.nPasswordLen = 4
test = GetHash(udt)
End sub
Code:
Public Type HASHINFO
pHash As String * 16
szPassword As String * 4
nPasswordLen As Long
End Type
Public Declare Function GetHash Lib "C:\md5\md5.dll" (ByRef xx As HASHINFO) As Long
extern "C" __declspec(dllexport) int GetHash(HASHINFO*);
Code:
typedef struct {
unsigned char* pHash; // Address of buffer for saving hash
unsigned char* szPassword; // Password
int nPasswordLen; // Password length
unsigned char* szSalt; // Salt
int nSaltLen; // Salt length
unsigned char* szName; // User name
int nNameLen; // User name length
DWORD dwFlags; // Flags
} HASHINFO;
Here is the VB
Code:
Private Type HASHINFO
hash As String
szPassword As String * 10
nPasswordLen As Long
szSalt As String * 10
nSaltLen As Long
szName As String * 10
nNameLen As Long
dwFlags As Long
End Type
Private Declare Sub GetHash Lib "c:\md5\md5.dll" (ByRef pudt As HASHINFO)
Code:
Private Sub Command1_Click()
Dim udt As HASHINFO
udt.hash = vbNullString
udt.szPassword = "test" & Chr(0)
udt.nNameLen = 4
udt.szSalt = "test" & Chr(0)
udt.nSaltLen = 4
udt.szName = "test" & Chr(0)
udt.nNameLen = 4
udt.dwFlags = 0
Call GetHash(udt)
End Sub
I just get a crash.
Anyone out there to help me?
What jumps out at me first is that the DLL UDT structure given above says (for the hash string) "Address of buffer for saving hash". That to me means it's a reference to the memory where the string is stored, not the actual string itself. If true, then might the VB UDT structure use a Long, not a string? Whichever it is, the other string members would be the same, no?
So basically, if the hash member and the string members are of the same type, you can't make them different in VB. They either have to both be fixed length strings, or variable length strings.
Incidentally, VB pads fixed length strings with zeros (Chr$(0) or vbNullChar) if you don't assign all the available characters. The value returned by Len(TheUDT) will always be the length of the structure in memory. When fixed length strings are defined in a UDT, the actual string is stored in the space allocated for the structure, thus will be included in the value returned by Len. On the other hand, variable length strings are not stored within the space in memory for the structure, because the string member is a reference to the location of the string, not the actual string.
Please remember to rate the posts and threads that you find useful.
How can something be both new and improved at the same time?
Private Sub Command1_Click()
testString = Space$(16)
Dim udt As HASHINFO
udt.pHash = VarPtr(testString)
udt.szPassword = "test"
udt.nPasswordLen = 4
test = GetHash(udt)
MsgBox udt.pHash
End Sub
Code:
Public Type HASHINFO
pHash As Long
szPassword As String
nPasswordLen As Long
End Type
Public Declare Function GetHash Lib "C:\md5\md5.dll" (ByRef udt As HASHINFO) As Long
Public testString As String * 16
Crash.
Looks like i'm following everything correctly.
-Buffered string to 16 bytes which I know is the return size
-Passing the references of the string as long from VB
-Only passing requires inputs for DLL others were omitted
I guess this dll probably just isn't callable from VB6
If you didn't change the declaration of the UDT so that pHash is a Long instead of a String, then it'll still have the same result. And again, it follows that the others would need to be the same.
I may just get curious enough to try some stuff with it myself.
Please remember to rate the posts and threads that you find useful.
How can something be both new and improved at the same time?
The Dll is not properly compiled for VB calling... (see this thread on VB forums for what i mean)
Right so this is the story...
The proper UDT you need is like this..
Code:
Public Type HASHINFO
pHash() As Byte
szPassword() As Byte
nPasswordLen As Long
szSalt() As Byte
nSaltLen As Long
szName() As Byte
nNameLen As Long
dwFlags As Long
End Type
If the calling convention is bad (no STDCALL) then also the string-constant versions of the UDT might work, as long as the calling convention is adapted or changed.
Bookmarks