Alright. Sorry I don't have the means to test and run it. Long time since I've had Eudemons or Delphi installed. One thing I've just spotted comparing my code to yours is, I've commented out the switching of slashes to backslashes, but I'm not sure whether this was done before or after I built it. I originally wrote the code for Conquer's WDF files, and as I recall, the hash was the same, but the file prepare method was different. Try removing that line and see if it works.
I'm not sure how LowerCase[] works getting the first element, but apparently AnsiLowerCase is preferred due to mixed encodings. Doubt that's the cause of the problem though. The rest of the code looks ok, but as you mentioned, the bit work with pascal makes it trickier to read. You could use pointers and match up with the C code line exactly though.
If you need to, attach OllyDbg to a running instance of Eudemons and stick a breakpoint on the string2id function. You'll be able to see the prepared filename on the stack to see what it should look like, and compare that to how yours looks. You might also wanna try building a DLL with the C code, using the __stdcall convention and call it from your pascal application.
Oh, and if it may help. Here's the algorithm written in C#, without assembly.
Code:
private static UInt32 CalculateStringHash(string filename)
{
UInt32 Hash=0xF4FA8928;
UInt32 A=0;
UInt32 B=0;
UInt32 dwTemp1=0x37A8470E;
UInt32 dwTemp2=0x7758B42B;
UInt32 dwTemp3=0;
UInt64 Carrier;
UInt32 Carry;
int fileNameIntCount,j=0;
UInt32[] fileNameInts = new UInt32[70];
byte[] fileNameBytes = Encoding.ASCII.GetBytes(filename.ToLower());
byte[] fileNameAdjusted = new byte[fileNameBytes.Length + (fileNameBytes.Length % 4 == 0 ? 0 : 4 - fileNameBytes.Length%4)];
fileNameBytes.CopyTo(fileNameAdjusted, 0);
BinaryReader reader = new BinaryReader(new MemoryStream(fileNameAdjusted, false));
for (fileNameIntCount = 0;fileNameIntCount < fileNameAdjusted.Length / 4; fileNameIntCount++)
{
fileNameInts[fileNameIntCount] = (UInt32)reader.ReadInt32();
}
fileNameInts[fileNameIntCount++] = 0x9BE74448;
fileNameInts[fileNameIntCount++] = 0x66F42C48;
for (j=0;j<fileNameIntCount;j++)
{
dwTemp3=0x267B0B11;
Hash = (( Hash << 1) | (Hash >> 31) );
dwTemp3 ^= Hash;
A=fileNameInts[j];
dwTemp1 ^= A;
dwTemp2 ^= A;
B = dwTemp3;
B += dwTemp2;
B = B | 0x2040801;
B = B & 0xBFEF7FDF;
Carrier = B;
Carrier *= dwTemp1;
A = (UInt32)(Carrier);
B = (UInt32)(Carrier >> 32);
if (B!=0) A += 1;
Carrier = A;
Carrier += B;
A = (UInt32)(Carrier);
Carry = (UInt32)(Carrier >> 32);
if (Carry!=0) A += 1;
B = dwTemp3;
B += dwTemp1;
B = B | 0x804021;
B = B & 0x7DFEFBFF;
dwTemp1 = A;
Carrier = dwTemp2;
Carrier *= B;
A = (UInt32)Carrier;
B = (UInt32)(Carrier >> 32);
Carrier = B;
Carrier += B;
B = (UInt32)(Carrier);
Carry = (UInt32)(Carrier >> 32);
if (Carry!=0) A += 1;
Carrier = A;
Carrier += B;
A = (UInt32)Carrier;
Carry = (UInt32)(Carrier >> 32);
if (Carry!=0) A += 2;
dwTemp2 = A;
}
Hash = dwTemp1 ^ dwTemp2;
return Hash;
}
If you're still having trouble and you've built & tested the original code, I'll DL the client again and resolve it.